xref: /openbsd/usr.bin/dig/lib/dns/include/dns/rdata.h (revision 1fb015a8)
1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef DNS_RDATA_H
18 #define DNS_RDATA_H 1
19 
20 /*****
21  ***** Module Info
22  *****/
23 
24 /*! \file dns/rdata.h
25  * \brief
26  * Provides facilities for manipulating DNS rdata, including conversions to
27  * and from wire format and text format.
28  *
29  * Given the large amount of rdata possible in a nameserver, it was important
30  * to come up with a very efficient way of storing rdata, but at the same
31  * time allow it to be manipulated.
32  *
33  * The decision was to store rdata in uncompressed wire format,
34  * and not to make it a fully abstracted object; i.e. certain parts of the
35  * server know rdata is stored that way.  This saves a lot of memory, and
36  * makes adding rdata to messages easy.  Having much of the server know
37  * the representation would be perilous, and we certainly don't want each
38  * user of rdata to be manipulating such a low-level structure.  This is
39  * where the rdata module comes in.  The module allows rdata handles to be
40  * created and attached to uncompressed wire format regions.  All rdata
41  * operations and conversions are done through these handles.
42  *
43  * Implementation Notes:
44  *
45  *\li	The routines in this module are expected to be synthesized by the
46  *	build process from a set of source files, one per rdata type.  For
47  *	portability, it's probably best that the building be done by a C
48  *	program.  Adding a new rdata type will be a simple matter of adding
49  *	a file to a directory and rebuilding the server.  *All* knowledge of
50  *	the format of a particular rdata type is in this file.
51  *
52  * MP:
53  *\li	Clients of this module must impose any required synchronization.
54  *
55  * Reliability:
56  *\li	This module deals with low-level byte streams.  Errors in any of
57  *	the functions are likely to crash the server or corrupt memory.
58  *
59  *\li	Rdata is typed, and the caller must know what type of rdata it has.
60  *	A caller that gets this wrong could crash the server.
61  *
62  *\li	The fromstruct() and tostruct() routines use a void * pointer to
63  *	represent the structure.  The caller must ensure that it passes a
64  *	pointer to the appropriate type, or the server could crash or memory
65  *	could be corrupted.
66  *
67  * Resources:
68  *\li	None.
69  *
70  * Security:
71  *
72  *\li	*** WARNING ***
73  *	dns_rdata_fromwire() deals with raw network data.  An error in
74  *	this routine could result in the failure or hijacking of the server.
75  *
76  * Standards:
77  *\li	RFC1035
78  *\li	Draft EDNS0 (0)
79  *\li	Draft EDNS1 (0)
80  *\li	Draft Binary Labels (2)
81  *\li	Draft Local Compression (1)
82  *\li	Various RFCs for particular types; these will be documented in the
83  *	 sources files of the types.
84  *
85  */
86 
87 /***
88  *** Imports
89  ***/
90 
91 #include <dns/types.h>
92 #include <dns/name.h>
93 #include <dns/message.h>
94 
95 /***
96  *** Types
97  ***/
98 
99 typedef struct dns_rdatacommon {
100 	dns_rdataclass_t			rdclass;
101 	dns_rdatatype_t				rdtype;
102 	ISC_LINK(struct dns_rdatacommon)	link;
103 } dns_rdatacommon_t;
104 
105 typedef struct dns_rdata_cname {
106 	dns_rdatacommon_t	common;
107 	dns_name_t		cname;
108 } dns_rdata_cname_t;
109 
110 typedef struct dns_rdata_ns {
111 	dns_rdatacommon_t	common;
112 	dns_name_t		name;
113 } dns_rdata_ns_t;
114 
115 typedef struct dns_rdata_soa {
116 	dns_rdatacommon_t	common;
117 	dns_name_t		origin;
118 	dns_name_t		contact;
119 	uint32_t		serial;		/*%< host order */
120 	uint32_t		refresh;	/*%< host order */
121 	uint32_t		retry;		/*%< host order */
122 	uint32_t		expire;		/*%< host order */
123 	uint32_t		minimum;	/*%< host order */
124 } dns_rdata_soa_t;
125 
126 typedef struct dns_rdata_any_tsig {
127 	dns_rdatacommon_t	common;
128 	dns_name_t		algorithm;
129 	uint64_t		timesigned;
130 	uint16_t		fudge;
131 	uint16_t		siglen;
132 	unsigned char *		signature;
133 	uint16_t		originalid;
134 	uint16_t		error;
135 	uint16_t		otherlen;
136 	unsigned char *		other;
137 } dns_rdata_any_tsig_t;
138 
139 /*%
140  ***** An 'rdata' is a handle to a binary region.  The handle has an RR
141  ***** class and type, and the data in the binary region is in the format
142  ***** of the given class and type.
143  *****/
144 /*%
145  * Clients are strongly discouraged from using this type directly, with
146  * the exception of the 'link' field which may be used directly for whatever
147  * purpose the client desires.
148  */
149 struct dns_rdata {
150 	unsigned char *			data;
151 	unsigned int			length;
152 	dns_rdataclass_t		rdclass;
153 	dns_rdatatype_t			type;
154 	unsigned int			flags;
155 	ISC_LINK(dns_rdata_t)		link;
156 };
157 
158 #define DNS_RDATA_INIT { NULL, 0, 0, 0, 0, {(void*)(-1), (void *)(-1)}}
159 
160 #define DNS_RDATA_INITIALIZED(rdata) \
161 	((rdata)->data == NULL && (rdata)->length == 0 && \
162 	 (rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \
163 	 !ISC_LINK_LINKED((rdata), link))
164 
165 #define DNS_RDATA_UPDATE	0x0001		/*%< update pseudo record. */
166 #define DNS_RDATA_OFFLINE	0x0002		/*%< RRSIG has a offline key. */
167 
168 #define DNS_RDATA_VALIDFLAGS(rdata) \
169 	(((rdata)->flags & ~(DNS_RDATA_UPDATE|DNS_RDATA_OFFLINE)) == 0)
170 
171 /*
172  * The maximum length of a RDATA that can be sent on the wire.
173  * Max packet size (65535) less header (12), less name (1), type (2),
174  * class (2), ttl(4), length (2).
175  *
176  * None of the defined types that support name compression can exceed
177  * this and all new types are to be sent uncompressed.
178  */
179 
180 #define DNS_RDATA_MAXLENGTH	65512U
181 
182 /*
183  * Flags affecting rdata formatting style.  Flags 0xFFFF0000
184  * are used by masterfile-level formatting and defined elsewhere.
185  * See additional comments at dns_rdata_tofmttext().
186  */
187 
188 /*% Split the rdata into multiple lines to try to keep it
189  within the "width". */
190 #define DNS_STYLEFLAG_MULTILINE		0x00000001ULL
191 
192 /*% Output explanatory comments. */
193 #define DNS_STYLEFLAG_COMMENT		0x00000002ULL
194 #define DNS_STYLEFLAG_RRCOMMENT		0x00000004ULL
195 
196 /*% Output KEYDATA in human readable format. */
197 #define DNS_STYLEFLAG_KEYDATA		0x00000008ULL
198 
199 /*% Output textual RR type and RDATA in RFC 3597 unknown format */
200 #define DNS_STYLEFLAG_UNKNOWNFORMAT	0x00000010ULL
201 
202 #define DNS_RDATA_DOWNCASE		DNS_NAME_DOWNCASE
203 #define DNS_RDATA_CHECKNAMES		DNS_NAME_CHECKNAMES
204 #define DNS_RDATA_CHECKNAMESFAIL	DNS_NAME_CHECKNAMESFAIL
205 #define DNS_RDATA_CHECKREVERSE		DNS_NAME_CHECKREVERSE
206 #define DNS_RDATA_CHECKMX		DNS_NAME_CHECKMX
207 #define DNS_RDATA_CHECKMXFAIL		DNS_NAME_CHECKMXFAIL
208 #define DNS_RDATA_UNKNOWNESCAPE		0x80000000
209 
210 /***
211  *** Initialization
212  ***/
213 
214 void
215 dns_rdata_init(dns_rdata_t *rdata);
216 /*%<
217  * Make 'rdata' empty.
218  *
219  * Requires:
220  *	'rdata' is a valid rdata (i.e. not NULL, points to a struct dns_rdata)
221  */
222 
223 void
224 dns_rdata_reset(dns_rdata_t *rdata);
225 /*%<
226  * Make 'rdata' empty.
227  *
228  * Requires:
229  *\li	'rdata' is a previously initialized rdata and is not linked.
230  */
231 
232 void
233 dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target);
234 /*%<
235  * Clone 'target' from 'src'.
236  *
237  * Requires:
238  *\li	'src' to be initialized.
239  *\li	'target' to be initialized.
240  */
241 
242 /***
243  *** Conversions
244  ***/
245 
246 void
247 dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
248 		     dns_rdatatype_t type, isc_region_t *r);
249 /*%<
250  * Make 'rdata' refer to region 'r'.
251  *
252  * Requires:
253  *
254  *\li	The data in 'r' is properly formatted for whatever type it is.
255  */
256 
257 void
258 dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r);
259 /*%<
260  * Make 'r' refer to 'rdata'.
261  */
262 
263 isc_result_t
264 dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
265 		   dns_rdatatype_t type, isc_buffer_t *source,
266 		   dns_decompress_t *dctx, unsigned int options,
267 		   isc_buffer_t *target);
268 /*%<
269  * Copy the possibly-compressed rdata at source into the target region.
270  *
271  * Notes:
272  *\li	Name decompression policy is controlled by 'dctx'.
273  *
274  *	'options'
275  *\li	DNS_RDATA_DOWNCASE	downcase domain names when they are copied
276  *				into target.
277  *
278  * Requires:
279  *
280  *\li	'rdclass' and 'type' are valid.
281  *
282  *\li	'source' is a valid buffer, and the active region of 'source'
283  *	references the rdata to be processed.
284  *
285  *\li	'target' is a valid buffer.
286  *
287  *\li	'dctx' is a valid decompression context.
288  *
289  * Ensures,
290  *	if result is success:
291  *	\li 	If 'rdata' is not NULL, it is attached to the target.
292  *	\li	The conditions dns_name_fromwire() ensures for names hold
293  *		for all names in the rdata.
294  *	\li	The current location in source is advanced, and the used space
295  *		in target is updated.
296  *
297  * Result:
298  *\li	Success
299  *\li	Any non-success status from dns_name_fromwire()
300  *\li	Various 'Bad Form' class failures depending on class and type
301  *\li	Bad Form: Input too short
302  *\li	Resource Limit: Not enough space
303  */
304 
305 isc_result_t
306 dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
307 		 isc_buffer_t *target);
308 /*%<
309  * Convert 'rdata' into wire format, compressing it as specified by the
310  * compression context 'cctx', and storing the result in 'target'.
311  *
312  * Notes:
313  *\li	If the compression context allows global compression, then the
314  *	global compression table may be updated.
315  *
316  * Requires:
317  *\li	'rdata' is a valid, non-empty rdata
318  *
319  *\li	target is a valid buffer
320  *
321  *\li	Any offsets specified in a global compression table are valid
322  *	for target.
323  *
324  * Ensures,
325  *	if the result is success:
326  *	\li	The used space in target is updated.
327  *
328  * Returns:
329  *\li	Success
330  *\li	Any non-success status from dns_name_towire()
331  *\li	Resource Limit: Not enough space
332  */
333 
334 isc_result_t
335 dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target);
336 /*%<
337  * Convert 'rdata' into text format, storing the result in 'target'.
338  * The text will consist of a single line, with fields separated by
339  * single spaces.
340  *
341  * Notes:
342  *\li	If 'origin' is not NULL, then any names in the rdata that are
343  *	subdomains of 'origin' will be made relative it.
344  *
345  *\li	XXX Do we *really* want to support 'origin'?  I'm inclined towards "no"
346  *	at the moment.
347  *
348  * Requires:
349  *
350  *\li	'rdata' is a valid, non-empty rdata
351  *
352  *\li	'origin' is NULL, or is a valid name
353  *
354  *\li	'target' is a valid text buffer
355  *
356  * Ensures,
357  *	if the result is success:
358  *
359  *	\li	The used space in target is updated.
360  *
361  * Returns:
362  *\li	Success
363  *\li	Any non-success status from dns_name_totext()
364  *\li	Resource Limit: Not enough space
365  */
366 
367 isc_result_t
368 dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin, unsigned int flags,
369 		    unsigned int width, unsigned int split_width,
370 		    const char *linebreak, isc_buffer_t *target);
371 /*%<
372  * Like dns_rdata_totext, but do formatted output suitable for
373  * database dumps.  This is intended for use by dns_db_dump();
374  * library users are discouraged from calling it directly.
375  *
376  * If (flags & #DNS_STYLEFLAG_MULTILINE) != 0, attempt to stay
377  * within 'width' by breaking the text into multiple lines.
378  * The string 'linebreak' is inserted between lines, and parentheses
379  * are added when necessary.  Because RRs contain unbreakable elements
380  * such as domain names whose length is variable, unpredictable, and
381  * potentially large, there is no guarantee that the lines will
382  * not exceed 'width' anyway.
383  *
384  * If (flags & #DNS_STYLEFLAG_MULTILINE) == 0, the rdata is always
385  * printed as a single line, and no parentheses are used.
386  * The 'width' and 'linebreak' arguments are ignored.
387  *
388  * If (flags & #DNS_STYLEFLAG_COMMENT) != 0, output explanatory
389  * comments next to things like the SOA timer fields.  Some
390  * comments (e.g., the SOA ones) are only printed when multiline
391  * output is selected.
392  *
393  * base64 rdata text (e.g., DNSKEY records) will be split into chunks
394  * of 'split_width' characters.  If split_width == 0, the text will
395  * not be split at all.  If split_width == UINT_MAX (0xffffffff), then
396  * it is undefined and falls back to the default value of 'width'
397  */
398 
399 isc_result_t
400 dns_rdata_fromstruct_soa(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
401 		          dns_rdatatype_t type, dns_rdata_soa_t *soa,
402 		          isc_buffer_t *target);
403 /*%<
404  * Convert the C structure representation of an rdata into uncompressed wire
405  * format in 'target'.
406  *
407  * XXX  Should we have a 'size' parameter as a sanity check on target?
408  *
409  * Requires:
410  *
411  *\li	'rdclass' and 'type' are valid.
412  *
413  *\li	'source' points to a valid C struct for the class and type.
414  *
415  *\li	'target' is a valid buffer.
416  *
417  *\li	All structure pointers to memory blocks should be NULL if their
418  *	corresponding length values are zero.
419  *
420  * Ensures,
421  *	if result is success:
422  *	\li 	If 'rdata' is not NULL, it is attached to the target.
423  *
424  *	\li	The used space in 'target' is updated.
425  *
426  * Result:
427  *\li	Success
428  *\li	Various 'Bad Form' class failures depending on class and type
429  *\li	Resource Limit: Not enough space
430  */
431 
432 isc_result_t
433 dns_rdata_fromstruct_tsig(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
434 		          dns_rdatatype_t type, dns_rdata_any_tsig_t *tsig,
435 		          isc_buffer_t *target);
436 /*%<
437  * Convert the C structure representation of an rdata into uncompressed wire
438  * format in 'target'.
439  *
440  * XXX  Should we have a 'size' parameter as a sanity check on target?
441  *
442  * Requires:
443  *
444  *\li	'rdclass' and 'type' are valid.
445  *
446  *\li	'source' points to a valid C struct for the class and type.
447  *
448  *\li	'target' is a valid buffer.
449  *
450  *\li	All structure pointers to memory blocks should be NULL if their
451  *	corresponding length values are zero.
452  *
453  * Ensures,
454  *	if result is success:
455  *	\li 	If 'rdata' is not NULL, it is attached to the target.
456  *
457  *	\li	The used space in 'target' is updated.
458  *
459  * Result:
460  *\li	Success
461  *\li	Various 'Bad Form' class failures depending on class and type
462  *\li	Resource Limit: Not enough space
463  */
464 
465 isc_result_t
466 dns_rdata_tostruct_cname(const dns_rdata_t *rdata, dns_rdata_cname_t *cname);
467 /*%<
468  * Convert an rdata into its C structure representation.
469  *
470  *
471  * Requires:
472  *
473  *\li	'rdata' is a valid, non-empty rdata.
474  *
475  *\li	'cname' to point to a valid pointer for the type and class.
476  *
477  * Result:
478  *\li	Success
479  *\li	Resource Limit: Not enough memory
480  */
481 
482 isc_result_t
483 dns_rdata_tostruct_ns(const dns_rdata_t *rdata, dns_rdata_ns_t *ns);
484 /*%<
485  * Convert an rdata into its C structure representation.
486  *
487  *
488  * Requires:
489  *
490  *\li	'rdata' is a valid, non-empty rdata.
491  *
492  *\li	'ns' to point to a valid pointer for the type and class.
493  *
494  * Result:
495  *\li	Success
496  *\li	Resource Limit: Not enough memory
497  */
498 
499 isc_result_t
500 dns_rdata_tostruct_soa(const dns_rdata_t *rdata, dns_rdata_soa_t *soa);
501 /*%<
502  * Convert an rdata into its C structure representation.
503  *
504  *
505  * Requires:
506  *
507  *\li	'rdata' is a valid, non-empty rdata.
508  *
509  *\li	'soa' to point to a valid pointer for the type and class.
510  *
511  * Result:
512  *\li	Success
513  *\li	Resource Limit: Not enough memory
514  */
515 
516 isc_result_t
517 dns_rdata_tostruct_tsig(const dns_rdata_t *rdata, dns_rdata_any_tsig_t *tsig);
518 /*%<
519  * Convert an rdata into its C structure representation.
520  *
521  *
522  * Requires:
523  *
524  *\li	'rdata' is a valid, non-empty rdata.
525  *
526  *\li	'tsig' to point to a valid pointer for the type and class.
527  *
528  * Result:
529  *\li	Success
530  *\li	Resource Limit: Not enough memory
531  */
532 
533 void
534 dns_rdata_freestruct_cname(dns_rdata_cname_t *cname);
535 /*%<
536  * Free dynamic memory attached to 'cname' (if any).
537  *
538  * Requires:
539  *
540  *\li	'cname' to point to the structure previously filled in by
541  *	dns_rdata_tostruct_cname().
542  */
543 
544 void
545 dns_rdata_freestruct_ns(dns_rdata_ns_t *ns);
546 /*%<
547  * Free dynamic memory attached to 'ns' (if any).
548  *
549  * Requires:
550  *
551  *\li	'ns' to point to the structure previously filled in by
552  *	dns_rdata_tostruct_ns().
553  */
554 
555 void
556 dns_rdata_freestruct_soa(dns_rdata_soa_t *soa);
557 /*%<
558  * Free dynamic memory attached to 'soa' (if any).
559  *
560  * Requires:
561  *
562  *\li	'soa' to point to the structure previously filled in by
563  *	dns_rdata_tostruct_soa().
564  */
565 
566 void
567 dns_rdata_freestruct_tsig(dns_rdata_any_tsig_t *tsig);
568 /*%<
569  * Free dynamic memory attached to 'tsig' (if any).
570  *
571  * Requires:
572  *
573  *\li	'tsig' to point to the structure previously filled in by
574  *	dns_rdata_tostruct_tsig().
575  */
576 
577 unsigned int
578 dns_rdatatype_attributes(dns_rdatatype_t rdtype);
579 /*%<
580  * Return attributes for the given type.
581  *
582  * Requires:
583  *\li	'rdtype' are known.
584  *
585  * Returns:
586  *\li	a bitmask consisting of the following flags.
587  */
588 
589 /*% Is reserved (unusable) */
590 #define DNS_RDATATYPEATTR_RESERVED		0x00000020U
591 /*% Is an unknown type */
592 #define DNS_RDATATYPEATTR_UNKNOWN		0x00000040U
593 
594 dns_rdatatype_t
595 dns_rdata_covers(dns_rdata_t *rdata);
596 /*%<
597  * Return the rdatatype that this type covers.
598  *
599  * Requires:
600  *\li	'rdata' is a valid, non-empty rdata.
601  *
602  *\li	'rdata' is a type that covers other rdata types.
603  *
604  * Returns:
605  *\li	The type covered.
606  */
607 
608 int
609 dns_rdata_checkowner_nsec3(dns_name_t* name, dns_rdataclass_t rdclass,
610 		     dns_rdatatype_t type, int wildcard);
611 /*
612  * Returns whether this is a valid ownername for this <type,class>.
613  * If wildcard is true allow the first label to be a wildcard if
614  * appropriate.
615  *
616  * Requires:
617  *	'name' is a valid name.
618  */
619 
620 #endif /* DNS_RDATA_H */
621