1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
|
/*!
* \file edns.h
*
* \author Lubos Slovak <lubos.slovak@nic.cz>
*
* \brief Functions for manipulating and parsing EDNS OPT pseudo-RR.
*
* \addtogroup libknot
* @{
*/
/* Copyright (C) 2011 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _KNOT_EDNS_H_
#define _KNOT_EDNS_H_
#include <stdint.h>
#include "util/utils.h"
#include "rrset.h"
/*----------------------------------------------------------------------------*/
/*! \brief Structure representing one OPT RR Option. */
struct knot_opt_option {
uint16_t code;
uint16_t length;
uint8_t *data;
};
/*! \brief Structure representing one OPT RR Option. */
typedef struct knot_opt_option knot_opt_option_t;
/*!
* \brief Structure for holding EDNS parameters.
*
* \todo NSID
*/
struct knot_opt_rr {
uint16_t payload; /*!< UDP payload. */
uint8_t ext_rcode; /*!< Extended RCODE. */
/*!
* \brief Supported version of EDNS.
*
* Set to EDNS_NOT_SUPPORTED if not supported.
*/
uint8_t version;
uint16_t flags; /*!< EDNS flags. */
knot_opt_option_t *options; /*!< EDNS options. */
short option_count; /*!< Count of EDNS options in this OPT RR.*/
short options_max; /*!< Maximum count of options. */
short size; /*!< Total size of the OPT RR in wire format. */
};
/*! \brief Structure for holding EDNS parameters. */
typedef struct knot_opt_rr knot_opt_rr_t;
/*----------------------------------------------------------------------------*/
/*! \brief Constants for supported versions of EDNS. */
enum knot_edns_versions {
EDNS_VERSION_0 = (uint8_t)0, /*!< EDNS version 0. */
EDNS_NOT_SUPPORTED = (uint8_t)255 /*!< EDNS not supported. */
};
/*! \brief Constants for EDNS option codes. */
enum knot_edns_option_codes {
EDNS_OPTION_NSID = (uint16_t)3 /*!< NSID option code. */
};
/*! \brief Minimum size of EDNS OPT RR in wire format. */
static const short KNOT_EDNS_MIN_SIZE = 11;
/*----------------------------------------------------------------------------*/
/*!
* \brief Creates new empty OPT RR structure for holding EDNS parameters.
*
* \return New empty knot_opt_rr_t structure, or NULL if not successful.
*/
knot_opt_rr_t *knot_edns_new();
/*!
* \brief Initializes OPT RR structure from given OPT RR in wire format.
*
* \param opt_rr OPT RR structure to initialize.
* \param wire Wire format of the OPT RR to parse.
* \param max_size Maximum size of the wire format in bytes (may be more
* than acutal size of the OPT RR).
*
* \return Size of the parserd OPT RR in bytes if successful (always > 0).
* \retval KNOT_EINVAL
* \retval KNOT_EFEWDATA
* \retval KNOT_EMALF
* \retval KNOT_ENOMEM
*/
int knot_edns_new_from_wire(knot_opt_rr_t *opt_rr, const uint8_t *wire,
size_t max_size);
int knot_edns_new_from_rr(knot_opt_rr_t *opt_rr,
const knot_rrset_t *rrset);
/*!
* \brief Returns the UDP payload stored in the OPT RR.
*
* \warning This function does not check the parameter, so ensure to check it
* before calling the function. It must not be NULL.
* \note There is an assert() for debug checking of the parameter.
*
* \param opt_rr OPT RR structure to get the payload from.
*
* \return UDP payload in bytes.
*/
uint16_t knot_edns_get_payload(const knot_opt_rr_t *opt_rr);
/*!
* \brief Sets the UDP payload field in the OPT RR.
*
* \warning This function does not check the parameter, so ensure to check it
* before calling the function. It must not be NULL.
* \note There is an assert() for debug checking of the parameter.
*
* \param opt_rr OPT RR structure to set the payload to.
* \param payload UDP payload in bytes.
*/
void knot_edns_set_payload(knot_opt_rr_t *opt_rr, uint16_t payload);
/*!
* \brief Returns the Extended RCODE stored in the OPT RR.
*
* \warning This function does not check the parameter, so ensure to check it
* before calling the function. It must not be NULL.
* \note There is an assert() for debug checking of the parameter.
*
* \param opt_rr OPT RR structure to get the Extended RCODE from.
*
* \return Extended RCODE.
*/
uint8_t knot_edns_get_ext_rcode(const knot_opt_rr_t *opt_rr);
/*!
* \brief Sets the Extended RCODE field in the OPT RR.
*
* \warning This function does not check the parameter, so ensure to check it
* before calling the function. It must not be NULL.
* \note There is an assert() for debug checking of the parameter.
*
* \param opt_rr OPT RR structure to set the Extended RCODE to.
* \param ext_rcode Extended RCODE to set.
*/
void knot_edns_set_ext_rcode(knot_opt_rr_t *opt_rr, uint8_t ext_rcode);
/*!
* \brief Returns the EDNS version stored in the OPT RR.
*
* \warning This function does not check the parameter, so ensure to check it
* before calling the function. It must not be NULL.
* \note There is an assert() for debug checking of the parameter.
*
* \param opt_rr OPT RR structure to get the EDNS version from.
*
* \return EDNS version.
*/
uint8_t knot_edns_get_version(const knot_opt_rr_t *opt_rr);
/*!
* \brief Sets the EDNS version field in the OPT RR.
*
* \warning This function does not check the parameter, so ensure to check it
* before calling the function. It must not be NULL.
* \note There is an assert() for debug checking of the parameter.
*
* \param opt_rr OPT RR structure to set the EDNS version to.
* \param version EDNS version to set.
*/
void knot_edns_set_version(knot_opt_rr_t *opt_rr, uint8_t version);
/*!
* \brief Returns the flags stored in the OPT RR.
*
* \warning This function does not check the parameter, so ensure to check it
* before calling the function. It must not be NULL.
* \note There is an assert() for debug checking of the parameter.
*
* \param opt_rr OPT RR structure to get the flags from.
*
* \return EDNS flags.
*/
uint16_t knot_edns_get_flags(const knot_opt_rr_t *opt_rr);
/*!
* \brief Returns the state of the DO bit in the OPT RR flags.
*
* \param opt_rr OPT RR structure to get the DO bit from.
*
* \return <> 0 if the DO bit is set.
* \return 0 if the DO bit is not set.
*/
int knot_edns_do(const knot_opt_rr_t *opt_rr);
/*!
* \brief Sets the DO bit in the OPT RR.
*
* \param opt_rr OPT RR structure to set the DO bit in.
*/
void knot_edns_set_do(knot_opt_rr_t *opt_rr);
/*!
* \brief Adds EDNS Option to the OPT RR.
*
* \param opt_rr OPT RR structure to add the Option to.
* \param code Option code.
* \param length Option data length in bytes.
* \param data Option data.
*
* \retval KNOT_EOK
* \retval KNOT_ENOMEM
*/
int knot_edns_add_option(knot_opt_rr_t *opt_rr, uint16_t code,
uint16_t length, const uint8_t *data);
/*!
* \brief Checks if the OPT RR contains Option with the specified code.
*
* \param opt_rr OPT RR structure to check for the Option in.
* \param code Option code to check for.
*
* \retval <> 0 if the OPT RR contains Option with Option code \a code.
* \retval 0 otherwise.
*/
int knot_edns_has_option(const knot_opt_rr_t *opt_rr, uint16_t code);
/*!
* \brief Converts the given OPT RR into wire format.
*
* \param opt_rr OPT RR structure to convert into wire format.
* \param wire Place to put the wire format to.
* \param max_size Maximum space available for the wire format in bytes.
*
* \return Size of the wire format in bytes if successful.
* \retval KNOT_ESPACE
*/
short knot_edns_to_wire(const knot_opt_rr_t *opt_rr, uint8_t *wire,
size_t max_size);
/*!
* \brief Returns size of the OPT RR in wire format.
*
* \param opt_rr OPT RR to get the size of.
*
* \return Size of the OPT RR in bytes.
*/
short knot_edns_size(knot_opt_rr_t *opt_rr);
void knot_edns_free_options(knot_opt_rr_t *opt_rr);
/*!
* \brief Properly destroys the OPT RR structure.
*
* \note Also sets the given pointer to NULL.
*/
void knot_edns_free(knot_opt_rr_t **opt_rr);
#endif /* _KNOT_EDNS_H_ */
/*! @} */
|