1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 /***
5   Copyright © 2014 Intel Corporation. All rights reserved.
6 ***/
7 
8 #include <errno.h>
9 #include <netinet/ip6.h>
10 #include <netinet/udp.h>
11 
12 #include "macro.h"
13 #include "sparse-endian.h"
14 
15 struct DHCP6Message {
16         union {
17                 struct {
18                         uint8_t type;
19                         uint8_t _pad[3];
20                 } _packed_;
21                 be32_t transaction_id;
22         };
23         uint8_t options[];
24 } _packed_;
25 
26 typedef struct DHCP6Message DHCP6Message;
27 
28 #define DHCP6_MIN_OPTIONS_SIZE \
29         1280 - sizeof(struct ip6_hdr) - sizeof(struct udphdr)
30 
31 #define IN6ADDR_ALL_DHCP6_RELAY_AGENTS_AND_SERVERS_INIT                 \
32         { { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,           \
33               0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02 } } }
34 
35 enum {
36         DHCP6_PORT_SERVER                       = 547,
37         DHCP6_PORT_CLIENT                       = 546,
38 };
39 
40 #define DHCP6_INF_TIMEOUT                       (1 * USEC_PER_SEC)
41 #define DHCP6_INF_MAX_RT                        (120 * USEC_PER_SEC)
42 #define DHCP6_SOL_MAX_DELAY                     (1 * USEC_PER_SEC)
43 #define DHCP6_SOL_TIMEOUT                       (1 * USEC_PER_SEC)
44 #define DHCP6_SOL_MAX_RT                        (120 * USEC_PER_SEC)
45 #define DHCP6_REQ_TIMEOUT                       (1 * USEC_PER_SEC)
46 #define DHCP6_REQ_MAX_RT                        (120 * USEC_PER_SEC)
47 #define DHCP6_REQ_MAX_RC                        10
48 #define DHCP6_REN_TIMEOUT                       (10 * USEC_PER_SEC)
49 #define DHCP6_REN_MAX_RT                        (600 * USEC_PER_SEC)
50 #define DHCP6_REB_TIMEOUT                       (10 * USEC_PER_SEC)
51 #define DHCP6_REB_MAX_RT                        (600 * USEC_PER_SEC)
52 
53 typedef enum DHCP6State {
54         DHCP6_STATE_STOPPED,
55         DHCP6_STATE_INFORMATION_REQUEST,
56         DHCP6_STATE_SOLICITATION,
57         DHCP6_STATE_REQUEST,
58         DHCP6_STATE_BOUND,
59         DHCP6_STATE_RENEW,
60         DHCP6_STATE_REBIND,
61         _DHCP6_STATE_MAX,
62         _DHCP6_STATE_INVALID = -EINVAL,
63 } DHCP6State;
64 
65 /* https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#dhcpv6-parameters-1 */
66 typedef enum DHCP6MessageType {
67         DHCP6_MESSAGE_SOLICIT                   = 1,  /* RFC 8415 */
68         DHCP6_MESSAGE_ADVERTISE                 = 2,  /* RFC 8415 */
69         DHCP6_MESSAGE_REQUEST                   = 3,  /* RFC 8415 */
70         DHCP6_MESSAGE_CONFIRM                   = 4,  /* RFC 8415 */
71         DHCP6_MESSAGE_RENEW                     = 5,  /* RFC 8415 */
72         DHCP6_MESSAGE_REBIND                    = 6,  /* RFC 8415 */
73         DHCP6_MESSAGE_REPLY                     = 7,  /* RFC 8415 */
74         DHCP6_MESSAGE_RELEASE                   = 8,  /* RFC 8415 */
75         DHCP6_MESSAGE_DECLINE                   = 9,  /* RFC 8415 */
76         DHCP6_MESSAGE_RECONFIGURE               = 10, /* RFC 8415 */
77         DHCP6_MESSAGE_INFORMATION_REQUEST       = 11, /* RFC 8415 */
78         DHCP6_MESSAGE_RELAY_FORWARD             = 12, /* RFC 8415 */
79         DHCP6_MESSAGE_RELAY_REPLY               = 13, /* RFC 8415 */
80         DHCP6_MESSAGE_LEASE_QUERY               = 14, /* RFC 5007 */
81         DHCP6_MESSAGE_LEASE_QUERY_REPLY         = 15, /* RFC 5007 */
82         DHCP6_MESSAGE_LEASE_QUERY_DONE          = 16, /* RFC 5460 */
83         DHCP6_MESSAGE_LEASE_QUERY_DATA          = 17, /* RFC 5460 */
84         DHCP6_MESSAGE_RECONFIGURE_REQUEST       = 18, /* RFC 6977 */
85         DHCP6_MESSAGE_RECONFIGURE_REPLY         = 19, /* RFC 6977 */
86         DHCP6_MESSAGE_DHCPV4_QUERY              = 20, /* RFC 7341 */
87         DHCP6_MESSAGE_DHCPV4_RESPONSE           = 21, /* RFC 7341 */
88         DHCP6_MESSAGE_ACTIVE_LEASE_QUERY        = 22, /* RFC 7653 */
89         DHCP6_MESSAGE_START_TLS                 = 23, /* RFC 7653 */
90         DHCP6_MESSAGE_BINDING_UPDATE            = 24, /* RFC 8156 */
91         DHCP6_MESSAGE_BINDING_REPLY             = 25, /* RFC 8156 */
92         DHCP6_MESSAGE_POOL_REQUEST              = 26, /* RFC 8156 */
93         DHCP6_MESSAGE_POOL_RESPONSE             = 27, /* RFC 8156 */
94         DHCP6_MESSAGE_UPDATE_REQUEST            = 28, /* RFC 8156 */
95         DHCP6_MESSAGE_UPDATE_REQUEST_ALL        = 29, /* RFC 8156 */
96         DHCP6_MESSAGE_UPDATE_DONE               = 30, /* RFC 8156 */
97         DHCP6_MESSAGE_CONNECT                   = 31, /* RFC 8156 */
98         DHCP6_MESSAGE_CONNECT_REPLY             = 32, /* RFC 8156 */
99         DHCP6_MESSAGE_DISCONNECT                = 33, /* RFC 8156 */
100         DHCP6_MESSAGE_STATE                     = 34, /* RFC 8156 */
101         DHCP6_MESSAGE_CONTACT                   = 35, /* RFC 8156 */
102         _DHCP6_MESSAGE_TYPE_MAX,
103         _DHCP6_MESSAGE_TYPE_INVALID             = -EINVAL,
104 } DHCP6MessageType;
105 
106 typedef enum DHCP6NTPSubOption {
107         DHCP6_NTP_SUBOPTION_SRV_ADDR            = 1,
108         DHCP6_NTP_SUBOPTION_MC_ADDR             = 2,
109         DHCP6_NTP_SUBOPTION_SRV_FQDN            = 3,
110         _DHCP6_NTP_SUBOPTION_MAX,
111         _DHCP6_NTP_SUBOPTION_INVALID            = -EINVAL,
112 } DHCP6NTPSubOption;
113 
114 /*
115  * RFC 8415, RFC 5007 and RFC 7653 status codes:
116  * https://www.iana.org/assignments/dhcpv6-parameters/dhcpv6-parameters.xhtml#dhcpv6-parameters-5
117  */
118 typedef enum DHCP6Status {
119         DHCP6_STATUS_SUCCESS                      = 0,
120         DHCP6_STATUS_UNSPEC_FAIL                  = 1,
121         DHCP6_STATUS_NO_ADDRS_AVAIL               = 2,
122         DHCP6_STATUS_NO_BINDING                   = 3,
123         DHCP6_STATUS_NOT_ON_LINK                  = 4,
124         DHCP6_STATUS_USE_MULTICAST                = 5,
125         DHCP6_STATUS_NO_PREFIX_AVAIL              = 6,
126         DHCP6_STATUS_UNKNOWN_QUERY_TYPE           = 7,
127         DHCP6_STATUS_MALFORMED_QUERY              = 8,
128         DHCP6_STATUS_NOT_CONFIGURED               = 9,
129         DHCP6_STATUS_NOT_ALLOWED                  = 10,
130         DHCP6_STATUS_QUERY_TERMINATED             = 11,
131         DHCP6_STATUS_DATA_MISSING                 = 12,
132         DHCP6_STATUS_CATCHUP_COMPLETE             = 13,
133         DHCP6_STATUS_NOT_SUPPORTED                = 14,
134         DHCP6_STATUS_TLS_CONNECTION_REFUSED       = 15,
135         DHCP6_STATUS_ADDRESS_IN_USE               = 16,
136         DHCP6_STATUS_CONFIGURATION_CONFLICT       = 17,
137         DHCP6_STATUS_MISSING_BINDING_INFORMATION  = 18,
138         DHCP6_STATUS_OUTDATED_BINDING_INFORMATION = 19,
139         DHCP6_STATUS_SERVER_SHUTTING_DOWN         = 20,
140         DHCP6_STATUS_DNS_UPDATE_NOT_SUPPORTED     = 21,
141         DHCP6_STATUS_EXCESSIVE_TIME_SKEW          = 22,
142         _DHCP6_STATUS_MAX,
143         _DHCP6_STATUS_INVALID                     = -EINVAL,
144 } DHCP6Status;
145 
146 typedef enum DHCP6FQDNFlag {
147         DHCP6_FQDN_FLAG_S = 1 << 0,
148         DHCP6_FQDN_FLAG_O = 1 << 1,
149         DHCP6_FQDN_FLAG_N = 1 << 2,
150 } DHCP6FQDNFlag;
151 
152 const char *dhcp6_state_to_string(DHCP6State s) _const_;
153 const char *dhcp6_message_type_to_string(DHCP6MessageType s) _const_;
154 DHCP6MessageType dhcp6_message_type_from_string(const char *s) _pure_;
155 const char *dhcp6_message_status_to_string(DHCP6Status s) _const_;
156 DHCP6Status dhcp6_message_status_from_string(const char *s) _pure_;
157