]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd-network/dhcp-identifier.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include "dhcp-identifier.h"
7 #include "dhcp6-protocol.h"
8 #include "network-internal.h"
10 #include "sparse-endian.h"
13 #define SYSTEMD_PEN 43793
14 #define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
16 int dhcp_validate_duid_len(uint16_t duid_type
, size_t duid_len
) {
19 assert_cc(sizeof(d
.raw
) >= MAX_DUID_LEN
);
20 if (duid_len
> MAX_DUID_LEN
)
25 if (duid_len
<= sizeof(d
.llt
))
29 if (duid_len
!= sizeof(d
.en
))
33 if (duid_len
<= sizeof(d
.ll
))
37 if (duid_len
!= sizeof(d
.uuid
))
41 /* accept unknown type in order to be forward compatible */
47 int dhcp_identifier_set_duid_en(struct duid
*duid
, size_t *len
) {
48 sd_id128_t machine_id
;
55 r
= sd_id128_get_machine(&machine_id
);
59 unaligned_write_be16(&duid
->type
, DUID_TYPE_EN
);
60 unaligned_write_be32(&duid
->en
.pen
, SYSTEMD_PEN
);
62 *len
= sizeof(duid
->type
) + sizeof(duid
->en
);
64 /* a bit of snake-oil perhaps, but no need to expose the machine-id
65 directly; duid->en.id might not be aligned, so we need to copy */
66 hash
= htole64(siphash24(&machine_id
, sizeof(machine_id
), HASH_KEY
.bytes
));
67 memcpy(duid
->en
.id
, &hash
, sizeof(duid
->en
.id
));
72 int dhcp_identifier_set_iaid(int ifindex
, uint8_t *mac
, size_t mac_len
, void *_id
) {
73 /* name is a pointer to memory in the sd_device struct, so must
74 * have the same scope */
75 _cleanup_(sd_device_unrefp
) sd_device
*device
= NULL
;
76 const char *name
= NULL
;
79 if (detect_container() <= 0) {
80 /* not in a container, udev will be around */
81 char ifindex_str
[2 + DECIMAL_STR_MAX(int)];
84 sprintf(ifindex_str
, "n%d", ifindex
);
85 if (sd_device_new_from_device_id(&device
, ifindex_str
) >= 0) {
86 r
= sd_device_get_is_initialized(device
, &initialized
);
93 name
= net_get_name(device
);
98 id
= siphash24(name
, strlen(name
), HASH_KEY
.bytes
);
100 /* fall back to MAC address if no predictable name available */
101 id
= siphash24(mac
, mac_len
, HASH_KEY
.bytes
);
105 /* fold into 32 bits */
106 unaligned_write_be32(_id
, (id
& 0xffffffff) ^ (id
>> 32));