The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
dhcpv6.h
Go to the documentation of this file.
1 #pragma once
2 /*
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16  */
17 
18 /**
19  * $Id: b9484cc5a4e2504dd813a9a2752e75f4a880e9e4 $
20  *
21  * @file protocols/dhcpv6/dhcpv6.h
22  * @brief Implementation of the DHCPv6 protocol.
23  *
24  * @author Arran Cudbard-Bell (a.cudbardb@freeradius.org)
25  *
26  * @copyright 2018 The FreeRADIUS server project
27  * @copyright 2018 NetworkRADIUS SARL (legal@networkradius.com)
28  */
29 RCSIDH(dhcpv6_h, "$Id: b9484cc5a4e2504dd813a9a2752e75f4a880e9e4 $")
30 
31 #include <freeradius-devel/util/dict.h>
32 
33 #include <freeradius-devel/protocol/dhcpv6/dictionary.h>
34 
35 #define DHCPV6_MSG_TYPE_LEN 1U
36 
37 #define DHCPV6_TRANSACTION_ID_LEN 3U
38 
39 #define DHCPV6_HOP_COUNT_LEN 1U
40 #define DHCPV6_LINK_ADDRESS_LEN 16U
41 #define DHCPV6_PEER_ADDRESS_LEN 16U
42 
43 #define DHCPV6_HDR_LEN (DHCPV6_MSG_TYPE_LEN + DHCPV6_TRANSACTION_ID_LEN)
44 #define DHCPV6_RELAY_HDR_LEN (DHCPV6_MSG_TYPE_LEN + DHCPV6_HOP_COUNT_LEN + DHCPV6_LINK_ADDRESS_LEN + DHCPV6_PEER_ADDRESS_LEN)
45 #define DHCPV6_OPT_HDR_LEN (sizeof(uint16_t) * 2)
46 
47 #define DHCPV6_GET_OPTION_NUM(_x) fr_nbo_to_uint16(_x)
48 #define DHCPV6_GET_OPTION_LEN(_x) fr_nbo_to_uint16((_x) + 2)
49 
50 #define DHCPV6_MAX_RELAY_NESTING 10
51 
52 #define DHCPV6_MAX_ATTRIBUTES 1024
53 
54 /*
55  * Defined addresses from RFC 8415 Section 7.1
56  */
57 #define IN6ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS "FF02::1:2"
58 #define IN6ADDR_ALL_DHCP_RELAY_AGENTS_AND_SERVERS_INIT {{{ 0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,1,2}}}
59 #define IN6ADDR_ALL_DHCP_SERVERS "FF05::1:3"
60 #define IN6ADDR_ALL_DHCP_SERVERS_INIT {{{ 0xff,0x05,0,0,0,0,0,0,0,0,0,0,0,0,1,3}}}
61 
62 /*
63  * Copied from src/include/protocols/dhcpv6/freeradius.internal.h
64  * and edited.
65  */
66 typedef enum {
106 
107 #define FR_DHCPV6_PACKET_CODE_VALID(_code) (((_code) > 0) && ((_code) < FR_DHCPV6_CODE_MAX))
108 
109 extern char const *fr_dhcpv6_packet_names[FR_DHCPV6_CODE_MAX];
110 
111 /** subtype values for DHCPv4 and DHCPv6
112  *
113  */
114 enum {
115  FLAG_ENCODE_NONE = 0, //!< no particular encoding for DHCPv6 strings
116  FLAG_ENCODE_DNS_LABEL, //!< encode as DNS label
117  FLAG_ENCODE_PARTIAL_DNS_LABEL, //!< encode as a partial DNS label
118 };
119 
120 #define da_is_dns_label(_da) (!(_da)->flags.extra && (((_da)->flags.subtype == FLAG_ENCODE_DNS_LABEL) || ((_da)->flags.subtype == FLAG_ENCODE_PARTIAL_DNS_LABEL)))
121 
122 typedef struct CC_HINT(__packed__) {
124  uint8_t transaction_id[3];
126 
127 /*
128  * DHCPv6 defines dates to start from Jan 1, 2000. Which is
129  * exactly this number of seconds off of the standard Unix time
130  * stamps.
131  */
132 #define DHCPV6_DATE_OFFSET (946684800)
133 
134 typedef struct {
135  fr_dict_attr_t const *root; //!< Root attribute of the dictionary.
136  uint8_t const *original; //!< original packet
137  size_t original_length; //!< length of the original packet
139 
140 typedef struct {
141  TALLOC_CTX *tmp_ctx; //!< for temporary things cleaned up during decoding
142  uint32_t transaction_id; //!< previous transaction ID
143  uint8_t *duid; //!< the expected DUID, in wire format
144  size_t duid_len; //!< length of the expected DUID
146 
147 /*
148  * base.c
149  */
150 uint8_t const *fr_dhcpv6_option_find(uint8_t const *start, uint8_t const *end, unsigned int option);
151 
152 bool fr_dhcpv6_ok(uint8_t const *packet, size_t packet_len,
153  uint32_t max_attributes);
154 
155 bool fr_dhcpv6_verify(uint8_t const *packet, size_t packet_len, fr_dhcpv6_decode_ctx_t const *packet_ctx,
156  bool from_server);
157 
158 ssize_t fr_dhcpv6_encode(fr_dbuff_t *dbuff, uint8_t const *original, size_t length,
159  int msg_type, fr_pair_list_t *vps);
160 
161 ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len);
162 
163 void fr_dhcpv6_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len);
164 
165 int fr_dhcpv6_global_init(void);
166 
167 void fr_dhcpv6_global_free(void);
168 
169 /*
170  * encode.c
171  */
173 
175 
176 /*
177  * decode.c
178  */
180  uint8_t const *data, size_t data_len, void *decode_ctx);
181 
183  uint8_t const *data, size_t data_len);
#define RCSIDH(h, id)
Definition: build.h:445
uint32_t transaction_id
previous transaction ID
Definition: dhcpv6.h:142
fr_dhcpv6_packet_code_t
Definition: dhcpv6.h:66
@ FR_DHCPV6_RELEASE
Definition: dhcpv6.h:75
@ FR_DHCPV6_DECLINE
Definition: dhcpv6.h:76
@ FR_DHCPV6_BIND_REPLY
Definition: dhcpv6.h:92
@ FR_DHCPV6_ADVERTISE
Definition: dhcpv6.h:69
@ FR_DHCPV6_ACTIVE_LEASE_QUERY
Definition: dhcpv6.h:89
@ FR_DHCPV6_DO_NOT_RESPOND
Definition: dhcpv6.h:104
@ FR_DHCPV6_REBIND
Definition: dhcpv6.h:73
@ FR_DHCPV6_POOL_REQUEST
Definition: dhcpv6.h:93
@ FR_DHCPV6_BIND_UPDATE
Definition: dhcpv6.h:91
@ FR_DHCPV6_REPLY
Definition: dhcpv6.h:74
@ FR_DHCPV6_LEASE_QUERY_DATA
Definition: dhcpv6.h:84
@ FR_DHCPV6_START_TLS
Definition: dhcpv6.h:90
@ FR_DHCPV6_POOL_RESPONSE
Definition: dhcpv6.h:94
@ FR_DHCPV6_INVALID
Definition: dhcpv6.h:67
@ FR_DHCPV6_CONTACT
Definition: dhcpv6.h:102
@ FR_DHCPV6_CONFIRM
Definition: dhcpv6.h:71
@ FR_DHCPV6_RECONFIGURE_REPLY
Definition: dhcpv6.h:86
@ FR_DHCPV6_DHCPV4_RESPONSE
Definition: dhcpv6.h:88
@ FR_DHCPV6_LEASE_QUERY
Definition: dhcpv6.h:81
@ FR_DHCPV6_RECONFIGURE_REQUEST
Definition: dhcpv6.h:85
@ FR_DHCPV6_UPDATE_REQUEST_ALL
Definition: dhcpv6.h:96
@ FR_DHCPV6_SOLICIT
Definition: dhcpv6.h:68
@ FR_DHCPV6_CONNECT_REPLY
Definition: dhcpv6.h:99
@ FR_DHCPV6_DISCONNECT
Definition: dhcpv6.h:100
@ FR_DHCPV6_UPDATE_DONE
Definition: dhcpv6.h:97
@ FR_DHCPV6_RENEW
Definition: dhcpv6.h:72
@ FR_DHCPV6_INFORMATION_REQUEST
Definition: dhcpv6.h:78
@ FR_DHCPV6_STATE
Definition: dhcpv6.h:101
@ FR_DHCPV6_LEASE_QUERY_DONE
Definition: dhcpv6.h:83
@ FR_DHCPV6_REQUEST
Definition: dhcpv6.h:70
@ FR_DHCPV6_DHCPV4_QUERY
Definition: dhcpv6.h:87
@ FR_DHCPV6_CODE_MAX
Definition: dhcpv6.h:103
@ FR_DHCPV6_CONNECT
Definition: dhcpv6.h:98
@ FR_DHCPV6_RECONFIGURE
Definition: dhcpv6.h:77
@ FR_DHCPV6_RELAY_FORWARD
Definition: dhcpv6.h:79
@ FR_DHCPV6_RELAY_REPLY
Definition: dhcpv6.h:80
@ FR_DHCPV6_LEASE_QUERY_REPLY
Definition: dhcpv6.h:82
@ FR_DHCPV6_UPDATE_REQUEST
Definition: dhcpv6.h:95
fr_dict_attr_t const * root
Root attribute of the dictionary.
Definition: dhcpv6.h:135
uint8_t const * fr_dhcpv6_option_find(uint8_t const *start, uint8_t const *end, unsigned int option)
Definition: base.c:243
void fr_dhcpv6_global_free(void)
Definition: base.c:938
ssize_t fr_dhcpv6_decode_option(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len, void *decode_ctx)
Create a "normal" fr_pair_t from the given data.
Definition: decode.c:421
bool fr_dhcpv6_ok(uint8_t const *packet, size_t packet_len, uint32_t max_attributes)
See if the data pointed to by PTR is a valid DHCPv6 packet.
Definition: base.c:227
uint8_t * duid
the expected DUID, in wire format
Definition: dhcpv6.h:143
int fr_dhcpv6_global_init(void)
Definition: base.c:896
ssize_t fr_dhcpv6_decode(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *packet, size_t packet_len)
Decode a DHCPv6 packet.
Definition: base.c:578
char const * fr_dhcpv6_packet_names[FR_DHCPV6_CODE_MAX]
Definition: base.c:71
uint8_t const * original
original packet
Definition: dhcpv6.h:136
ssize_t fr_dhcpv6_encode_option(fr_dbuff_t *dbuff, fr_dcursor_t *cursor, void *encode_ctx)
Encode a DHCPv6 option and any sub-options.
Definition: encode.c:670
size_t original_length
length of the original packet
Definition: dhcpv6.h:137
@ FLAG_ENCODE_NONE
no particular encoding for DHCPv6 strings
Definition: dhcpv6.h:115
@ FLAG_ENCODE_PARTIAL_DNS_LABEL
encode as a partial DNS label
Definition: dhcpv6.h:117
@ FLAG_ENCODE_DNS_LABEL
encode as DNS label
Definition: dhcpv6.h:116
bool fr_dhcpv6_verify(uint8_t const *packet, size_t packet_len, fr_dhcpv6_decode_ctx_t const *packet_ctx, bool from_server)
Verify the packet under some various circumstances.
Definition: base.c:544
void fr_dhcpv6_print_hex(FILE *fp, uint8_t const *packet, size_t packet_len)
Print a raw DHCP packet as hex.
Definition: base.c:891
size_t duid_len
length of the expected DUID
Definition: dhcpv6.h:144
TALLOC_CTX * tmp_ctx
for temporary things cleaned up during decoding
Definition: dhcpv6.h:141
ssize_t fr_dhcpv6_decode_foreign(TALLOC_CTX *ctx, fr_pair_list_t *out, uint8_t const *data, size_t data_len)
Definition: decode.c:436
ssize_t fr_dhcpv6_encode_foreign(fr_dbuff_t *dbuff, fr_pair_list_t const *list)
Definition: encode.c:721
uint8_t code
Definition: dhcpv6.h:123
ssize_t fr_dhcpv6_encode(fr_dbuff_t *dbuff, uint8_t const *original, size_t length, int msg_type, fr_pair_list_t *vps)
Encode a DHCPv6 packet.
Definition: base.c:717
unsigned int uint32_t
Definition: merged_model.c:33
long int ssize_t
Definition: merged_model.c:24
unsigned char uint8_t
Definition: merged_model.c:30
static fr_internal_encode_ctx_t encode_ctx
static fr_slen_t data
Definition: value.h:1259
static size_t char ** out
Definition: value.h:984