1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 #include "sd-id128.h"
5 
6 #include "macro.h"
7 #include "sparse-endian.h"
8 #include "time-util.h"
9 #include "unaligned.h"
10 
11 #define SYSTEMD_PEN    43793
12 
13 typedef enum DUIDType {
14         DUID_TYPE_LLT       = 1,
15         DUID_TYPE_EN        = 2,
16         DUID_TYPE_LL        = 3,
17         DUID_TYPE_UUID      = 4,
18         _DUID_TYPE_MAX,
19         _DUID_TYPE_INVALID  = -EINVAL,
20 } DUIDType;
21 
22 /* RFC 3315 section 9.1:
23  *      A DUID can be no more than 128 octets long (not including the type code).
24  */
25 #define MAX_DUID_LEN 128
26 
27 /* https://tools.ietf.org/html/rfc3315#section-9.1 */
28 struct duid {
29         be16_t type;
30         union {
31                 struct {
32                         /* DUID_TYPE_LLT */
33                         be16_t htype;
34                         be32_t time;
35                         uint8_t haddr[0];
36                 } _packed_ llt;
37                 struct {
38                         /* DUID_TYPE_EN */
39                         be32_t pen;
40                         uint8_t id[8];
41                 } _packed_ en;
42                 struct {
43                         /* DUID_TYPE_LL */
44                         be16_t htype;
45                         uint8_t haddr[0];
46                 } _packed_ ll;
47                 struct {
48                         /* DUID_TYPE_UUID */
49                         sd_id128_t uuid;
50                 } _packed_ uuid;
51                 struct {
52                         uint8_t data[MAX_DUID_LEN];
53                 } _packed_ raw;
54         };
55 } _packed_;
56 
57 int dhcp_validate_duid_len(DUIDType duid_type, size_t duid_len, bool strict);
58 int dhcp_identifier_set_duid_en(bool test_mode, struct duid *ret_duid, size_t *ret_len);
59 int dhcp_identifier_set_duid(
60                 DUIDType duid_type,
61                 const uint8_t *addr,
62                 size_t addr_len,
63                 uint16_t arp_type,
64                 usec_t llt_time,
65                 bool test_mode,
66                 struct duid *ret_duid,
67                 size_t *ret_len);
68 int dhcp_identifier_set_iaid(
69                 int ifindex,
70                 const uint8_t *mac,
71                 size_t mac_len,
72                 bool legacy_unstable_byteorder,
73                 bool use_mac,
74                 void *ret);
75 
76 const char *duid_type_to_string(DUIDType t) _const_;
77