1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
7  *
8  * See the COPYRIGHT file distributed with this work for additional
9  * information regarding copyright ownership.
10  */
11 
12 #ifndef LWRES_LWRES_H
13 #define LWRES_LWRES_H 1
14 
15 #include <inttypes.h>
16 #include <stdio.h>
17 
18 #include <lwres/context.h>
19 #include <lwres/lang.h>
20 #include <lwres/list.h>
21 #include <lwres/lwpacket.h>
22 #include <lwres/platform.h>
23 
24 /*! \file lwres/lwres.h */
25 
26 /*!
27  * Design notes:
28  *
29  * Each opcode has two structures and three functions which operate on each
30  * structure.  For example, using the "no operation/ping" opcode as an
31  * example:
32  *
33  *	<ul><li>lwres_nooprequest_t:
34  *
35  *		lwres_nooprequest_render() takes a lwres_nooprequest_t and
36  *		and renders it into wire format, storing the allocated
37  *		buffer information in a passed-in buffer.  When this buffer
38  *		is no longer needed, it must be freed by
39  *		lwres_context_freemem().  All other memory used by the
40  *		caller must be freed manually, including the
41  *		lwres_nooprequest_t passed in.<br /><br />
42  *
43  *		lwres_nooprequest_parse() takes a wire format message and
44  *		breaks it out into a lwres_nooprequest_t.  The structure
45  *		must be freed via lwres_nooprequest_free() when it is no longer
46  *		needed.<br /><br />
47  *
48  *		lwres_nooprequest_free() releases into the lwres_context_t
49  *		any space allocated during parsing.</li>
50  *
51  *	<li>lwres_noopresponse_t:
52  *
53  *		The functions used are similar to the three used for
54  *		requests, just with different names.</li></ul>
55  *
56  * Typically, the client will use request_render, response_parse, and
57  * response_free, while the daemon will use request_parse, response_render,
58  * and request_free.
59  *
60  * The basic flow of a typical client is:
61  *
62  *	\li fill in a request_t, and call the render function.
63  *
64  *	\li Transmit the buffer returned to the daemon.
65  *
66  *	\li Wait for a response.
67  *
68  *	\li When a response is received, parse it into a response_t.
69  *
70  *	\li free the request buffer using lwres_context_freemem().
71  *
72  *	\li free the response structure and its associated buffer using
73  *	response_free().
74  */
75 
76 #define LWRES_UDP_PORT		921	/*%< UDP Port Number */
77 #define LWRES_RECVLENGTH	16384 /*%< Maximum Packet Length */
78 #define LWRES_ADDR_MAXLEN	16	/*%< changing this breaks ABI */
79 #define LWRES_RESOLV_CONF	"/etc/resolv.conf" /*%< Location of resolv.conf */
80 
81 /*% DNSSEC is not required (input).  Only relevant to rrset queries. */
82 #define LWRES_FLAG_TRUSTNOTREQUIRED	0x00000001U
83 /*% The data was crypto-verified with DNSSEC (output). */
84 #define LWRES_FLAG_SECUREDATA		0x00000002U
85 
86 /*% no-op */
87 #define LWRES_OPCODE_NOOP		0x00000000U
88 
89 /*% lwres_nooprequest_t */
90 typedef struct {
91 	/* public */
92 	uint16_t			datalength;
93 	unsigned char		       *data;
94 } lwres_nooprequest_t;
95 
96 /*% lwres_noopresponse_t */
97 typedef struct {
98 	/* public */
99 	uint16_t			datalength;
100 	unsigned char		       *data;
101 } lwres_noopresponse_t;
102 
103 /*% get addresses by name */
104 #define LWRES_OPCODE_GETADDRSBYNAME	0x00010001U
105 
106 /*% lwres_addr_t */
107 typedef struct lwres_addr lwres_addr_t;
108 
109 /*% LWRES_LIST */
110 typedef LWRES_LIST(lwres_addr_t) lwres_addrlist_t;
111 
112 /*% lwres_addr */
113 struct lwres_addr {
114 	uint32_t			family;
115 	uint16_t			length;
116 	unsigned char			address[LWRES_ADDR_MAXLEN];
117 	uint32_t			zone;
118 	LWRES_LINK(lwres_addr_t)	link;
119 };
120 
121 /*% lwres_gabnrequest_t */
122 typedef struct {
123 	/* public */
124 	uint32_t			flags;
125 	uint32_t			addrtypes;
126 	uint16_t			namelen;
127 	char			       *name;
128 } lwres_gabnrequest_t;
129 
130 /*% lwres_gabnresponse_t */
131 typedef struct {
132 	/* public */
133 	uint32_t			flags;
134 	uint16_t			naliases;
135 	uint16_t			naddrs;
136 	char			       *realname;
137 	char			      **aliases;
138 	uint16_t			realnamelen;
139 	uint16_t		       *aliaslen;
140 	lwres_addrlist_t		addrs;
141 	/*! if base != NULL, it will be freed when this structure is freed. */
142 	void			       *base;
143 	size_t				baselen;
144 } lwres_gabnresponse_t;
145 
146 /*% get name by address */
147 #define LWRES_OPCODE_GETNAMEBYADDR	0x00010002U
148 
149 /*% lwres_gnbarequest_t */
150 typedef struct {
151 	/* public */
152 	uint32_t			flags;
153 	lwres_addr_t			addr;
154 } lwres_gnbarequest_t;
155 
156 /*% lwres_gnbaresponse_t */
157 typedef struct {
158 	/* public */
159 	uint32_t			flags;
160 	uint16_t			naliases;
161 	char			       *realname;
162 	char			      **aliases;
163 	uint16_t			realnamelen;
164 	uint16_t		       *aliaslen;
165 	/*! if base != NULL, it will be freed when this structure is freed. */
166 	void			       *base;
167 	size_t				baselen;
168 } lwres_gnbaresponse_t;
169 
170 /*% get rdata by name */
171 #define LWRES_OPCODE_GETRDATABYNAME	0x00010003U
172 
173 /*% lwres_grbnrequest_t */
174 typedef struct {
175 	/* public */
176 	uint32_t			flags;
177 	uint16_t			rdclass;
178 	uint16_t			rdtype;
179 	uint16_t			namelen;
180 	char			       *name;
181 } lwres_grbnrequest_t;
182 
183 /*% lwres_grbnresponse_t */
184 typedef struct {
185 	/* public */
186 	uint32_t			flags;
187 	uint16_t			rdclass;
188 	uint16_t			rdtype;
189 	uint32_t			ttl;
190 	uint16_t			nrdatas;
191 	uint16_t			nsigs;
192 	char			       *realname;
193 	uint16_t			realnamelen;
194 	unsigned char		      **rdatas;
195 	uint16_t		       *rdatalen;
196 	unsigned char		      **sigs;
197 	uint16_t		       *siglen;
198 	/*% if base != NULL, it will be freed when this structure is freed. */
199 	void			       *base;
200 	size_t				baselen;
201 } lwres_grbnresponse_t;
202 
203 /*% Used by lwres_getrrsetbyname() */
204 #define LWRDATA_VALIDATED	0x00000001
205 
206 /*!
207  * resolv.conf data
208  */
209 
210 #define LWRES_CONFMAXNAMESERVERS 3	/*%< max 3 "nameserver" entries */
211 #define LWRES_CONFMAXLWSERVERS 1	/*%< max 1 "lwserver" entry */
212 #define LWRES_CONFMAXSEARCH 8		/*%< max 8 domains in "search" entry */
213 #define LWRES_CONFMAXLINELEN 256	/*%< max size of a line */
214 #define LWRES_CONFMAXSORTLIST 10	/*%< max 10 */
215 
216 /*% lwres_conf_t */
217 typedef struct {
218 	lwres_context_t *lwctx;
219 	lwres_addr_t    nameservers[LWRES_CONFMAXNAMESERVERS];
220 	uint8_t	nsnext;		/*%< index for next free slot */
221 
222 	lwres_addr_t	lwservers[LWRES_CONFMAXLWSERVERS];
223 	uint8_t	lwnext;		/*%< index for next free slot */
224 
225 	char	       *domainname;
226 
227 	char 	       *search[LWRES_CONFMAXSEARCH];
228 	uint8_t	searchnxt;	/*%< index for next free slot */
229 
230 	struct {
231 		lwres_addr_t addr;
232 		/*% mask has a non-zero 'family' and 'length' if set */
233 		lwres_addr_t mask;
234 	} sortlist[LWRES_CONFMAXSORTLIST];
235 	uint8_t	sortlistnxt;
236 
237 	uint8_t	resdebug;      /*%< non-zero if 'options debug' set */
238 	uint8_t	ndots;	       /*%< set to n in 'options ndots:n' */
239 	uint8_t	no_tld_query;  /*%< non-zero if 'options no_tld_query' */
240 	int32_t	attempts;      /*%< set to n in 'options attempts:n' */
241 	int32_t	timeout;       /*%< set to n in 'options timeout:n' */
242 } lwres_conf_t;
243 
244 #define LWRES_ADDRTYPE_V4		0x00000001U	/*%< ipv4 */
245 #define LWRES_ADDRTYPE_V6		0x00000002U	/*%< ipv6 */
246 
247 #define LWRES_MAX_ALIASES		16		/*%< max # of aliases */
248 #define LWRES_MAX_ADDRS			64		/*%< max # of addrs */
249 
250 LWRES_LANG_BEGINDECLS
251 
252 /*% This is in host byte order. */
253 LIBLWRES_EXTERNAL_DATA extern uint16_t lwres_udp_port;
254 
255 LIBLWRES_EXTERNAL_DATA extern const char *lwres_resolv_conf;
256 
257 lwres_result_t
258 lwres_gabnrequest_render(lwres_context_t *ctx, lwres_gabnrequest_t *req,
259 			 lwres_lwpacket_t *pkt, lwres_buffer_t *b);
260 
261 lwres_result_t
262 lwres_gabnresponse_render(lwres_context_t *ctx, lwres_gabnresponse_t *req,
263 			  lwres_lwpacket_t *pkt, lwres_buffer_t *b);
264 
265 lwres_result_t
266 lwres_gabnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
267 			lwres_lwpacket_t *pkt, lwres_gabnrequest_t **structp);
268 
269 lwres_result_t
270 lwres_gabnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
271 			 lwres_lwpacket_t *pkt,
272 			 lwres_gabnresponse_t **structp);
273 
274 void
275 lwres_gabnrequest_free(lwres_context_t *ctx, lwres_gabnrequest_t **structp);
276 /**<
277  * Frees any dynamically allocated memory for this structure.
278  *
279  * Requires:
280  *
281  *	ctx != NULL, and be a context returned via lwres_context_create().
282  *
283  *	structp != NULL && *structp != NULL.
284  *
285  * Ensures:
286  *
287  *	*structp == NULL.
288  *
289  *	All memory allocated by this structure will be returned to the
290  *	system via the context's free function.
291  */
292 
293 void
294 lwres_gabnresponse_free(lwres_context_t *ctx, lwres_gabnresponse_t **structp);
295 /**<
296  * Frees any dynamically allocated memory for this structure.
297  *
298  * Requires:
299  *
300  *	ctx != NULL, and be a context returned via lwres_context_create().
301  *
302  *	structp != NULL && *structp != NULL.
303  *
304  * Ensures:
305  *
306  *	*structp == NULL.
307  *
308  *	All memory allocated by this structure will be returned to the
309  *	system via the context's free function.
310  */
311 
312 
313 lwres_result_t
314 lwres_gnbarequest_render(lwres_context_t *ctx, lwres_gnbarequest_t *req,
315 			 lwres_lwpacket_t *pkt, lwres_buffer_t *b);
316 
317 lwres_result_t
318 lwres_gnbaresponse_render(lwres_context_t *ctx, lwres_gnbaresponse_t *req,
319 			  lwres_lwpacket_t *pkt, lwres_buffer_t *b);
320 
321 lwres_result_t
322 lwres_gnbarequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
323 			lwres_lwpacket_t *pkt, lwres_gnbarequest_t **structp);
324 
325 lwres_result_t
326 lwres_gnbaresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
327 			 lwres_lwpacket_t *pkt,
328 			 lwres_gnbaresponse_t **structp);
329 
330 void
331 lwres_gnbarequest_free(lwres_context_t *ctx, lwres_gnbarequest_t **structp);
332 /**<
333  * Frees any dynamically allocated memory for this structure.
334  *
335  * Requires:
336  *
337  *	ctx != NULL, and be a context returned via lwres_context_create().
338  *
339  *	structp != NULL && *structp != NULL.
340  *
341  * Ensures:
342  *
343  *	*structp == NULL.
344  *
345  *	All memory allocated by this structure will be returned to the
346  *	system via the context's free function.
347  */
348 
349 void
350 lwres_gnbaresponse_free(lwres_context_t *ctx, lwres_gnbaresponse_t **structp);
351 /**<
352  * Frees any dynamically allocated memory for this structure.
353  *
354  * Requires:
355  *
356  *	ctx != NULL, and be a context returned via lwres_context_create().
357  *
358  *	structp != NULL && *structp != NULL.
359  *
360  * Ensures:
361  *
362  *	*structp == NULL.
363  *
364  *	All memory allocated by this structure will be returned to the
365  *	system via the context's free function.
366  */
367 
368 lwres_result_t
369 lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
370 			 lwres_lwpacket_t *pkt, lwres_buffer_t *b);
371 
372 lwres_result_t
373 lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
374 			  lwres_lwpacket_t *pkt, lwres_buffer_t *b);
375 
376 lwres_result_t
377 lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
378 			lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp);
379 
380 lwres_result_t
381 lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
382 			 lwres_lwpacket_t *pkt,
383 			 lwres_grbnresponse_t **structp);
384 
385 void
386 lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp);
387 /**<
388  * Frees any dynamically allocated memory for this structure.
389  *
390  * Requires:
391  *
392  *	ctx != NULL, and be a context returned via lwres_context_create().
393  *
394  *	structp != NULL && *structp != NULL.
395  *
396  * Ensures:
397  *
398  *	*structp == NULL.
399  *
400  *	All memory allocated by this structure will be returned to the
401  *	system via the context's free function.
402  */
403 
404 void
405 lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp);
406 /**<
407  * Frees any dynamically allocated memory for this structure.
408  *
409  * Requires:
410  *
411  *	ctx != NULL, and be a context returned via lwres_context_create().
412  *
413  *	structp != NULL && *structp != NULL.
414  *
415  * Ensures:
416  *
417  *	*structp == NULL.
418  *
419  *	All memory allocated by this structure will be returned to the
420  *	system via the context's free function.
421  */
422 
423 lwres_result_t
424 lwres_nooprequest_render(lwres_context_t *ctx, lwres_nooprequest_t *req,
425 			 lwres_lwpacket_t *pkt, lwres_buffer_t *b);
426 /**<
427  * Allocate space and render into wire format a noop request packet.
428  *
429  * Requires:
430  *
431  *	ctx != NULL, and be a context returned via lwres_context_create().
432  *
433  *	b != NULL, and points to a lwres_buffer_t.  The contents of the
434  *	buffer structure will be initialized to contain the wire-format
435  *	noop request packet.
436  *
437  *	Caller needs to fill in parts of "pkt" before calling:
438  *		serial, maxrecv, result.
439  *
440  * Returns:
441  *
442  *	Returns 0 on success, non-zero on failure.
443  *
444  *	On successful return, *b will contain data about the wire-format
445  *	packet.  It can be transmitted in any way, including lwres_sendblock().
446  */
447 
448 lwres_result_t
449 lwres_noopresponse_render(lwres_context_t *ctx, lwres_noopresponse_t *req,
450 			  lwres_lwpacket_t *pkt, lwres_buffer_t *b);
451 
452 lwres_result_t
453 lwres_nooprequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
454 			lwres_lwpacket_t *pkt, lwres_nooprequest_t **structp);
455 /**<
456  * Parse a noop request.  Note that to get here, the lwpacket must have
457  * already been parsed and removed by the caller, otherwise it would be
458  * pretty hard for it to know this is the right function to call.
459  *
460  * The function verifies bits of the header, but does not modify it.
461  */
462 
463 lwres_result_t
464 lwres_noopresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
465 			 lwres_lwpacket_t *pkt,
466 			 lwres_noopresponse_t **structp);
467 
468 void
469 lwres_nooprequest_free(lwres_context_t *ctx, lwres_nooprequest_t **structp);
470 
471 void
472 lwres_noopresponse_free(lwres_context_t *ctx, lwres_noopresponse_t **structp);
473 
474 /**<
475  * Frees any dynamically allocated memory for this structure.
476  *
477  * Requires:
478  *
479  *	ctx != NULL, and be a context returned via lwres_context_create().
480  *
481  *	structp != NULL && *structp != NULL.
482  *
483  * Ensures:
484  *
485  *	*structp == NULL.
486  *
487  *	All memory allocated by this structure will be returned to the
488  *	system via the context's free function.
489  */
490 
491 lwres_result_t
492 lwres_conf_parse(lwres_context_t *ctx, const char *filename);
493 /**<
494  * parses a resolv.conf-format file and stores the results in the structure
495  * pointed to by *ctx.
496  *
497  * Requires:
498  *	ctx != NULL
499  *	filename != NULL && strlen(filename) > 0
500  *
501  * Returns:
502  *	LWRES_R_SUCCESS on a successful parse.
503  *	Anything else on error, although the structure may be partially filled
504  *	in.
505  */
506 
507 lwres_result_t
508 lwres_conf_print(lwres_context_t *ctx, FILE *fp);
509 /**<
510  * Prints a resolv.conf-format of confdata output to fp.
511  *
512  * Requires:
513  *	ctx != NULL
514  */
515 
516 void
517 lwres_conf_init(lwres_context_t *ctx);
518 /**<
519  * sets all internal fields to a default state. Used to initialize a new
520  * lwres_conf_t structure (not reset a used on).
521  *
522  * Requires:
523  *	ctx != NULL
524  */
525 
526 void
527 lwres_conf_clear(lwres_context_t *ctx);
528 /**<
529  * frees all internally allocated memory in confdata. Uses the memory
530  * routines supplied by ctx.
531  *
532  * Requires:
533  *	ctx != NULL
534  */
535 
536 lwres_conf_t *
537 lwres_conf_get(lwres_context_t *ctx);
538 /**<
539  * Be extremely cautions in modifying the contents of this structure; it
540  * needs an API to return the various bits of data, walk lists, etc.
541  *
542  * Requires:
543  *	ctx != NULL
544  */
545 
546 /*
547  * Helper functions
548  */
549 
550 lwres_result_t
551 lwres_data_parse(lwres_buffer_t *b, unsigned char **p, uint16_t *len);
552 
553 lwres_result_t
554 lwres_string_parse(lwres_buffer_t *b, char **c, uint16_t *len);
555 
556 lwres_result_t
557 lwres_addr_parse(lwres_buffer_t *b, lwres_addr_t *addr);
558 
559 lwres_result_t
560 lwres_getaddrsbyname(lwres_context_t *ctx, const char *name,
561 		     uint32_t addrtypes, lwres_gabnresponse_t **structp);
562 
563 lwres_result_t
564 lwres_getnamebyaddr(lwres_context_t *ctx, uint32_t addrtype,
565 		    uint16_t addrlen, const unsigned char *addr,
566 		    lwres_gnbaresponse_t **structp);
567 
568 lwres_result_t
569 lwres_getrdatabyname(lwres_context_t *ctx, const char *name,
570 		     uint16_t rdclass, uint16_t rdtype,
571 		     uint32_t flags, lwres_grbnresponse_t **structp);
572 
573 LWRES_LANG_ENDDECLS
574 
575 #endif /* LWRES_LWRES_H */
576