chiark / gitweb /
sd-dhcp6-client: Initialize DUID
authorTom Gundersen <teg@jklm.no>
Thu, 19 Jun 2014 12:39:01 +0000 (15:39 +0300)
committerPatrik Flykt <patrik.flykt@linux.intel.com>
Thu, 19 Jun 2014 12:44:43 +0000 (15:44 +0300)
Initialize DHCP Unique Identifier when creating the client. The
DUID is generated based on the machine-id, which satisfies all the
requirements of what an DUID should be. The DUID type is DUID-EN.

Based on patch by Patrik Flykt.

src/libsystemd-network/sd-dhcp6-client.c

index 5063d4a4c5b9759add5dbac27ba78bbde4ac12e1..8718324c339a0153cab80f86f9d251b74058af83 100644 (file)
 #include <errno.h>
 #include <string.h>
 
+#include "siphash24.h"
 #include "util.h"
 #include "refcnt.h"
 
 #include "sd-dhcp6-client.h"
 #include "dhcp6-protocol.h"
 
+#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)
+
 struct sd_dhcp6_client {
         RefCount n_ref;
 
@@ -38,6 +42,12 @@ struct sd_dhcp6_client {
         struct ether_addr mac_addr;
         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;
 };
 
 int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
@@ -185,6 +195,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp6_client*, sd_dhcp6_client_unref);
 int sd_dhcp6_client_new(sd_dhcp6_client **ret)
 {
         _cleanup_dhcp6_client_free_ sd_dhcp6_client *client = NULL;
+        sd_id128_t machine_id;
+        int r;
 
         assert_return(ret, -EINVAL);
 
@@ -196,6 +208,19 @@ int sd_dhcp6_client_new(sd_dhcp6_client **ret)
 
         client->index = -1;
 
+        /* initialize DUID */
+        client->duid.type = htobe16(DHCP6_DUID_EN);
+        client->duid.pen = htobe32(SYSTEMD_PEN);
+
+        r = sd_id128_get_machine(&machine_id);
+        if (r < 0)
+                return r;
+
+        /* 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);
+
         *ret = client;
         client = NULL;