[systemd-commits] 4 commits - src/libsystemd-network src/systemd

Tom Gundersen tomegun at kemper.freedesktop.org
Thu Oct 2 10:07:50 PDT 2014


 src/libsystemd-network/sd-dhcp6-client.c |   86 ++++++++++++++++++++++++++-----
 src/systemd/sd-dhcp6-client.h            |    2 
 2 files changed, 76 insertions(+), 12 deletions(-)

New commits:
commit fe4b2156256c5bdf52341576571ce9f095d9f085
Author: Tom Gundersen <teg at jklm.no>
Date:   Thu Oct 2 16:25:08 2014 +0200

    sd-dhcp6: do basic sanity-checking of supplied DUID

diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 42ad418..6ea68c9 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -69,11 +69,26 @@ struct sd_dhcp6_client {
         void *userdata;
         union {
                 struct {
+                        uint16_t type; /* DHCP6_DUID_LLT */
+                        uint16_t htype;
+                        uint32_t time;
+                        uint8_t haddr[0];
+                } _packed_ llt;
+                struct {
                         uint16_t type; /* DHCP6_DUID_EN */
                         uint32_t pen;
                         uint8_t id[8];
                 } _packed_ en;
                 struct {
+                        uint16_t type; /* DHCP6_DUID_LL */
+                        uint16_t htype;
+                        uint8_t haddr[0];
+                } _packed_ ll;
+                struct {
+                        uint16_t type; /* DHCP6_DUID_UUID */
+                        sd_id128_t uuid;
+                } _packed_ uuid;
+                struct {
                         uint16_t type;
                         uint8_t data[MAX_DUID_LEN];
                 } _packed_ raw;
@@ -165,6 +180,28 @@ int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *du
         assert_return(duid, -EINVAL);
         assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
 
+        switch (type) {
+        case DHCP6_DUID_LLT:
+                if (duid_len <= sizeof(client->duid.llt))
+                        return -EINVAL;
+                break;
+        case DHCP6_DUID_EN:
+                if (duid_len != sizeof(client->duid.en))
+                        return -EINVAL;
+                break;
+        case DHCP6_DUID_LL:
+                if (duid_len <= sizeof(client->duid.ll))
+                        return -EINVAL;
+                break;
+        case DHCP6_DUID_UUID:
+                if (duid_len != sizeof(client->duid.uuid))
+                        return -EINVAL;
+                break;
+        default:
+                /* accept unknown type in order to be forward compatible */
+                break;
+        }
+
         client->duid.raw.type = htobe16(type);
         memcpy(&client->duid.raw.data, duid, duid_len);
         client->duid_len = duid_len;

commit ebe207d4acf38165adbc45298662982eecdb9e9f
Author: Tom Gundersen <teg at jklm.no>
Date:   Thu Oct 2 16:04:20 2014 +0200

    sd-dhcp6: specify the type explicitly when setting custom DUID
    
    This would make it simple to verify that the data is on the right format when
    the type is known.

diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index ad6c5eb..42ad418 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -67,7 +67,17 @@ struct sd_dhcp6_client {
         sd_event_source *timeout_resend_expire;
         sd_dhcp6_client_cb_t cb;
         void *userdata;
-        uint8_t duid[MAX_DUID_LEN];
+        union {
+                struct {
+                        uint16_t type; /* DHCP6_DUID_EN */
+                        uint32_t pen;
+                        uint8_t id[8];
+                } _packed_ en;
+                struct {
+                        uint16_t type;
+                        uint8_t data[MAX_DUID_LEN];
+                } _packed_ raw;
+        } duid;
         size_t duid_len;
 };
 
@@ -148,14 +158,15 @@ int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
         return 0;
 }
 
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint8_t *duid,
+int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid,
                              size_t duid_len)
 {
         assert_return(client, -EINVAL);
         assert_return(duid, -EINVAL);
         assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
 
-        memcpy(&client->duid, duid, duid_len);
+        client->duid.raw.type = htobe16(type);
+        memcpy(&client->duid.raw.data, duid, duid_len);
         client->duid_len = duid_len;
 
         return 0;
@@ -1130,16 +1141,9 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
         return client;
 }
 
-struct duid_en {
-        uint16_t type; /* DHCP6_DUID_EN */
-        uint32_t pen;
-        uint8_t id[8];
-} _packed_;
-
 int sd_dhcp6_client_new(sd_dhcp6_client **ret)
 {
         _cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL;
-        struct duid_en *duid;
         sd_id128_t machine_id;
         int r;
         size_t t;
@@ -1159,9 +1163,9 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret)
         client->fd = -1;
 
         /* initialize DUID */
-        duid = (struct duid_en *) &client->duid;
-        duid->type = htobe16(DHCP6_DUID_EN);
-        duid->pen = htobe32(SYSTEMD_PEN);
+        client->duid.en.type = htobe16(DHCP6_DUID_EN);
+        client->duid.en.pen = htobe32(SYSTEMD_PEN);
+        client->duid_len = sizeof(client->duid.en);
 
         r = sd_id128_get_machine(&machine_id);
         if (r < 0)
@@ -1169,8 +1173,7 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret)
 
         /* a bit of snake-oil perhaps, but no need to expose the machine-id
            directly */
-        siphash24(duid->id, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
-        client->duid_len = sizeof (struct duid_en);
+        siphash24(client->duid.en.id, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
 
         client->req_opts_len = ELEMENTSOF(default_req_opts);
 
diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h
index 7b7f098..a4409e8 100644
--- a/src/systemd/sd-dhcp6-client.h
+++ b/src/systemd/sd-dhcp6-client.h
@@ -45,7 +45,7 @@ int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
 int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
 int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
                             const struct ether_addr *mac_addr);
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint8_t *duid,
+int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t type, uint8_t *duid,
                              size_t duid_len);
 int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
                                        uint16_t option);

commit 9547267dc56d5bf84b8119dfcb8e101202fac7d3
Author: Tom Gundersen <teg at jklm.no>
Date:   Thu Oct 2 16:00:55 2014 +0200

    sd-dhcp6: support custom DUID's up to the size specified in the RFC

diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 130fe43..ad6c5eb 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -39,7 +39,10 @@
 #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)
 
-#define MAX_DUID_LEN 32
+/* 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 sd_dhcp6_client {
         RefCount n_ref;

commit 66eac1201a9c1596f5901f8dbbf24bda7e350878
Author: Dan Williams <dcbw at redhat.com>
Date:   Fri Sep 26 15:12:36 2014 -0500

    sd-dhcp6-client: support custom DUIDs
    
    The caller may have an existing DUID that it wants to use, and may
    want to use some other DUID generation scheme than systemd's
    default DUID-EN.
    
    [tomegun: whitespace - we never use tabs]

diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index c190b56..130fe43 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -39,6 +39,8 @@
 #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)
 
+#define MAX_DUID_LEN 32
+
 struct sd_dhcp6_client {
         RefCount n_ref;
 
@@ -62,12 +64,8 @@ struct sd_dhcp6_client {
         sd_event_source *timeout_resend_expire;
         sd_dhcp6_client_cb_t cb;
         void *userdata;
-
-        struct duid_en {
-                uint16_t type; /* DHCP6_DUID_EN */
-                uint32_t pen;
-                uint8_t id[8];
-        } _packed_ duid;
+        uint8_t duid[MAX_DUID_LEN];
+        size_t duid_len;
 };
 
 static const uint16_t default_req_opts[] = {
@@ -147,6 +145,19 @@ int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
         return 0;
 }
 
+int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint8_t *duid,
+                             size_t duid_len)
+{
+        assert_return(client, -EINVAL);
+        assert_return(duid, -EINVAL);
+        assert_return(duid_len > 0 && duid_len <= MAX_DUID_LEN, -EINVAL);
+
+        memcpy(&client->duid, duid, duid_len);
+        client->duid_len = duid_len;
+
+        return 0;
+}
+
 int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
                                        uint16_t option) {
         size_t t;
@@ -308,7 +319,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
                 return r;
 
         r = dhcp6_option_append(&opt, &optlen, DHCP6_OPTION_CLIENTID,
-                                sizeof(client->duid), &client->duid);
+                                client->duid_len, &client->duid);
         if (r < 0)
                 return r;
 
@@ -616,7 +627,7 @@ static int client_parse_message(sd_dhcp6_client *client,
                                 return -EINVAL;
                         }
 
-                        if (optlen != sizeof(client->duid) ||
+                        if (optlen != client->duid_len ||
                             memcmp(&client->duid, optval, optlen) != 0) {
                                 log_dhcp6_client(client, "%s DUID does not match",
                                                  dhcp6_message_type_to_string(message->type));
@@ -1116,9 +1127,16 @@ sd_dhcp6_client *sd_dhcp6_client_unref(sd_dhcp6_client *client) {
         return client;
 }
 
+struct duid_en {
+        uint16_t type; /* DHCP6_DUID_EN */
+        uint32_t pen;
+        uint8_t id[8];
+} _packed_;
+
 int sd_dhcp6_client_new(sd_dhcp6_client **ret)
 {
         _cleanup_dhcp6_client_unref_ sd_dhcp6_client *client = NULL;
+        struct duid_en *duid;
         sd_id128_t machine_id;
         int r;
         size_t t;
@@ -1138,8 +1156,9 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret)
         client->fd = -1;
 
         /* initialize DUID */
-        client->duid.type = htobe16(DHCP6_DUID_EN);
-        client->duid.pen = htobe32(SYSTEMD_PEN);
+        duid = (struct duid_en *) &client->duid;
+        duid->type = htobe16(DHCP6_DUID_EN);
+        duid->pen = htobe32(SYSTEMD_PEN);
 
         r = sd_id128_get_machine(&machine_id);
         if (r < 0)
@@ -1147,8 +1166,8 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret)
 
         /* a bit of snake-oil perhaps, but no need to expose the machine-id
            directly */
-        siphash24(client->duid.id, &machine_id, sizeof(machine_id),
-                  HASH_KEY.bytes);
+        siphash24(duid->id, &machine_id, sizeof(machine_id), HASH_KEY.bytes);
+        client->duid_len = sizeof (struct duid_en);
 
         client->req_opts_len = ELEMENTSOF(default_req_opts);
 
diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h
index 93edcc4..7b7f098 100644
--- a/src/systemd/sd-dhcp6-client.h
+++ b/src/systemd/sd-dhcp6-client.h
@@ -45,6 +45,8 @@ int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
 int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
 int sd_dhcp6_client_set_mac(sd_dhcp6_client *client,
                             const struct ether_addr *mac_addr);
+int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint8_t *duid,
+                             size_t duid_len);
 int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
                                        uint16_t option);
 



More information about the systemd-commits mailing list