1 /*  Copyright (C) 2018 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
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 3 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, see <https://www.gnu.org/licenses/>.
15  */
16 
17 /*!
18  * \file
19  *
20  * \brief Value transformations for Yparser.
21  *
22  * \addtogroup yparser
23  * @{
24  */
25 
26 #pragma once
27 
28 #include "libknot/yparser/ypschema.h"
29 #include "libknot/lookup.h"
30 #include "libknot/wire.h"
31 
32 /*!
33  * Transforms textual item value to binary form.
34  *
35  * \param[in] item Schema item to transform.
36  * \param[in] txt Value to transform.
37  * \param[in] txt_len Value length.
38  * \param[out] bin Output buffer.
39  * \param[in, out] bin_len Output buffer length, output length.
40  *
41  * \return Error code, KNOT_EOK if success.
42  */
43 int yp_item_to_bin(
44 	const yp_item_t *item,
45 	const char *txt,
46 	size_t txt_len,
47 	uint8_t *bin,
48 	size_t *bin_len
49 );
50 
51 /*!
52  * Transforms binary item value to textual form.
53  *
54  * \param[in] item Schema item to transform.
55  * \param[in] bin Value to transform.
56  * \param[in] bin_len Value length.
57  * \param[out] txt Output buffer.
58  * \param[in, out] txt_len Output buffer length, output length.
59  * \param[in] style Value style.
60  *
61  * \return Error code, KNOT_EOK if success.
62  */
63 int yp_item_to_txt(
64 	const yp_item_t *item,
65 	const uint8_t *bin,
66 	size_t bin_len,
67 	char *txt,
68 	size_t *txt_len,
69 	yp_style_t style
70 );
71 
72 /*!
73  * Converts binary value to string pointer.
74  *
75  * \param[in] data Binary value to transform.
76  *
77  * \return String pointer.
78  */
yp_str(const uint8_t * data)79 inline static const char* yp_str(
80 	const uint8_t *data)
81 {
82 	return (const char *)data;
83 }
84 
85 /*!
86  * Converts binary value to boolean value.
87  *
88  * \param[in] data Binary value to transform.
89  *
90  * \return Boolean value.
91  */
yp_bool(const uint8_t * data)92 inline static bool yp_bool(
93 	const uint8_t *data)
94 {
95 	return (data[0] == 0) ? false : true;
96 }
97 
98 /*!
99  * Converts binary value to integer value.
100  *
101  * \param[in] data Binary value to transform.
102  *
103  * \return Integer value.
104  */
yp_int(const uint8_t * data)105 inline static int64_t yp_int(
106 	const uint8_t *data)
107 {
108 	return (int64_t)knot_wire_read_u64(data);
109 }
110 
111 /*!
112  * Converts binary value to address value.
113  *
114  * \param[in] data Binary value to transform.
115  *
116  * \return Address value.
117  */
118 struct sockaddr_storage yp_addr_noport(
119 	const uint8_t *data
120 );
121 
122 /*!
123  * Converts binary value to address value with an optional port.
124  *
125  * \param[in] data Binary value to transform.
126  * \param[out] no_port No port indicator.
127  *
128  * \return Address value.
129  */
130 struct sockaddr_storage yp_addr(
131 	const uint8_t *data,
132 	bool *no_port
133 );
134 
135 /*!
136  * Converts binary value to option value.
137  *
138  * \param[in] data Binary value to transform.
139  *
140  * \return Unsigned value.
141  */
yp_opt(const uint8_t * data)142 inline static unsigned yp_opt(
143 	const uint8_t *data)
144 {
145 	return (unsigned)data[0];
146 }
147 
148 /*!
149  * Converts binary value to dname pointer.
150  *
151  * \param[in] data Binary value to transform.
152  *
153  * \return Dname pointer.
154  */
yp_dname(const uint8_t * data)155 inline static const uint8_t* yp_dname(
156 	const uint8_t *data)
157 {
158 	return data;
159 }
160 
161 /*!
162  * Converts binary value to data pointer.
163  *
164  * Applies to all data types with 2-byte length prefix (YP_THEX, YP_TB64).
165  *
166  * \param[in] data Binary value to transform.
167  *
168  * \return Data pointer.
169  */
yp_bin(const uint8_t * data)170 inline static const uint8_t* yp_bin(
171 	const uint8_t *data)
172 {
173 	return data + 2;
174 }
175 
176 /*!
177  * Gets binary value length.
178  *
179  * Applies to all data types with 2-byte length prefix (YP_THEX, YP_TB64).
180  *
181  * \param[in] data Binary value to transform.
182  *
183  * \return Data length.
184  */
yp_bin_len(const uint8_t * data)185 inline static size_t yp_bin_len(
186 	const uint8_t *data)
187 {
188 	return knot_wire_read_u16(data);
189 }
190 
191 /*!
192  * \brief Helper macros for conversion functions.
193  */
194 
195 #define YP_CHECK_CTX \
196 	if (in->error != KNOT_EOK) { \
197 		return in->error; \
198 	} else if (out->error != KNOT_EOK) { \
199 		return out->error; \
200 	} \
201 
202 #define YP_CHECK_STOP \
203 	if (stop != NULL) { \
204 		assert(stop <= in->position + wire_ctx_available(in)); \
205 	} else { \
206 		stop = in->position + wire_ctx_available(in); \
207 	}
208 
209 #define YP_LEN (stop - in->position)
210 
211 #define YP_CHECK_PARAMS_BIN \
212 	YP_CHECK_CTX YP_CHECK_STOP
213 
214 #define YP_CHECK_PARAMS_TXT \
215 	YP_CHECK_CTX
216 
217 #define YP_CHECK_RET \
218 	YP_CHECK_CTX return KNOT_EOK;
219 
220 /*!
221  * \brief Conversion functions for basic types.
222  */
223 
224 int yp_str_to_bin(
225 	YP_TXT_BIN_PARAMS
226 );
227 
228 int yp_str_to_txt(
229 	YP_BIN_TXT_PARAMS
230 );
231 
232 int yp_bool_to_bin(
233 	YP_TXT_BIN_PARAMS
234 );
235 
236 int yp_bool_to_txt(
237 	YP_BIN_TXT_PARAMS
238 );
239 
240 int yp_int_to_bin(
241 	YP_TXT_BIN_PARAMS,
242 	int64_t min,
243 	int64_t max,
244 	yp_style_t style
245 );
246 
247 int yp_int_to_txt(
248 	YP_BIN_TXT_PARAMS,
249 	yp_style_t style
250 );
251 
252 int yp_addr_noport_to_bin(
253 	YP_TXT_BIN_PARAMS,
254 	bool allow_unix
255 );
256 
257 int yp_addr_noport_to_txt(
258 	YP_BIN_TXT_PARAMS
259 );
260 
261 int yp_addr_to_bin(
262 	YP_TXT_BIN_PARAMS
263 );
264 
265 int yp_addr_to_txt(
266 	YP_BIN_TXT_PARAMS
267 );
268 
269 int yp_addr_range_to_bin(
270 	YP_TXT_BIN_PARAMS
271 );
272 
273 int yp_addr_range_to_txt(
274 	YP_BIN_TXT_PARAMS
275 );
276 
277 int yp_option_to_bin(
278 	YP_TXT_BIN_PARAMS,
279 	const struct knot_lookup *opts
280 );
281 
282 int yp_option_to_txt(
283 	YP_BIN_TXT_PARAMS,
284 	const struct knot_lookup *opts
285 );
286 
287 int yp_dname_to_bin(
288 	YP_TXT_BIN_PARAMS
289 );
290 
291 int yp_dname_to_txt(
292 	YP_BIN_TXT_PARAMS
293 );
294 
295 int yp_hex_to_bin(
296 	YP_TXT_BIN_PARAMS
297 );
298 
299 int yp_hex_to_txt(
300 	YP_BIN_TXT_PARAMS
301 );
302 
303 int yp_base64_to_bin(
304 	YP_TXT_BIN_PARAMS
305 );
306 
307 int yp_base64_to_txt(
308 	YP_BIN_TXT_PARAMS
309 );
310 
311 /*! @} */
312