]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-dhcp: use application specific machine ID when DUIDType=uuid but DUIDRawData=...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 25 Jun 2018 09:23:13 +0000 (18:23 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 8 Aug 2018 01:15:00 +0000 (10:15 +0900)
src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/dhcp-identifier.h
src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp6-client.c

index 91c485c6c25dd767bcd8cd20a9038664b30d69dd..4b7e7ee0ab2861c7cea3263e0ff2a69a44e75adb 100644 (file)
@@ -11,8 +11,9 @@
 #include "udev-util.h"
 #include "virt.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)
+#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 APPLICATION_ID SD_ID128_MAKE(a5,0a,d1,12,bf,60,45,77,a2,fb,74,1a,b1,95,5b,03)
 
 int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
         struct duid d;
@@ -63,13 +64,32 @@ int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
         *len = sizeof(duid->type) + sizeof(duid->en);
 
         /* a bit of snake-oil perhaps, but no need to expose the machine-id
-           directly; duid->en.id might not be aligned, so we need to copy */
+         * directly; duid->en.id might not be aligned, so we need to copy */
         hash = htole64(siphash24(&machine_id, sizeof(machine_id), HASH_KEY.bytes));
         memcpy(duid->en.id, &hash, sizeof(duid->en.id));
 
         return 0;
 }
 
+int dhcp_identifier_set_duid_uuid(struct duid *duid, size_t *len) {
+        sd_id128_t machine_id;
+        int r;
+
+        assert(duid);
+        assert(len);
+
+        r = sd_id128_get_machine_app_specific(APPLICATION_ID, &machine_id);
+        if (r < 0)
+                return r;
+
+        unaligned_write_be16(&duid->type, DUID_TYPE_UUID);
+        memcpy(&duid->raw.data, &machine_id, sizeof(machine_id));
+
+        *len = sizeof(duid->type) + sizeof(machine_id);
+
+        return 0;
+}
+
 int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id) {
         /* name is a pointer to memory in the udev_device struct, so must
            have the same scope */
index 8250c765980492b5d2a22d02af20e15a27cdfff4..add546f31c1de7dc8d082fdc270f3a43f9283e4e 100644 (file)
@@ -53,4 +53,5 @@ struct duid {
 
 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_duid_uuid(struct duid *duid, size_t *len);
 int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
index ff434f8ce709923253db650415a810ea223e3eef..1b891420537a66b322a54970c0a31e1452e22eb3 100644 (file)
@@ -381,12 +381,21 @@ static int dhcp_client_set_iaid_duid(
                 client->client_id.ns.duid.type = htobe16(duid_type);
                 memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
                 len = sizeof(client->client_id.ns.duid.type) + duid_len;
-        } else if (duid_type == DUID_TYPE_EN) {
-                r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
-                if (r < 0)
-                        return r;
         } else
-                return -EOPNOTSUPP;
+                switch (duid_type) {
+                case DUID_TYPE_EN:
+                        r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
+                        if (r < 0)
+                                return r;
+                        break;
+                case DUID_TYPE_UUID:
+                        r = dhcp_identifier_set_duid_uuid(&client->client_id.ns.duid, &len);
+                        if (r < 0)
+                                return r;
+                        break;
+                default:
+                        return -EOPNOTSUPP;
+                }
 
         client->client_id_len = sizeof(client->client_id.type) + len +
                                 (append_iaid ? sizeof(client->client_id.ns.iaid) : 0);
index ff54d7e20c97043d4d6643613efae9f08e62ccf3..31382b5431125e85b9532688d452985eafc89e94 100644 (file)
@@ -187,8 +187,8 @@ int sd_dhcp6_client_set_duid(
                 uint16_t duid_type,
                 const void *duid,
                 size_t duid_len) {
-
         int r;
+
         assert_return(client, -EINVAL);
         assert_return(duid_len == 0 || duid != NULL, -EINVAL);
         assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
@@ -197,18 +197,25 @@ int sd_dhcp6_client_set_duid(
                 r = dhcp_validate_duid_len(duid_type, duid_len);
                 if (r < 0)
                         return r;
-        }
 
-        if (duid != NULL) {
                 client->duid.type = htobe16(duid_type);
                 memcpy(&client->duid.raw.data, duid, duid_len);
                 client->duid_len = sizeof(client->duid.type) + duid_len;
-        } else if (duid_type == DUID_TYPE_EN) {
-                r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
-                if (r < 0)
-                        return r;
         } else
-                return -EOPNOTSUPP;
+                switch (duid_type) {
+                case DUID_TYPE_EN:
+                        r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
+                        if (r < 0)
+                                return r;
+                        break;
+                case DUID_TYPE_UUID:
+                        r = dhcp_identifier_set_duid_uuid(&client->duid, &client->duid_len);
+                        if (r < 0)
+                                return r;
+                        break;
+                default:
+                        return -EOPNOTSUPP;
+                }
 
         return 0;
 }