1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * SPDX-License-Identifier: MPL-2.0
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 #ifndef DNS_RDATA_H
15 #define DNS_RDATA_H 1
16 
17 /*****
18 ***** Module Info
19 *****/
20 
21 /*! \file dns/rdata.h
22  * \brief
23  * Provides facilities for manipulating DNS rdata, including conversions to
24  * and from wire format and text format.
25  *
26  * Given the large amount of rdata possible in a nameserver, it was important
27  * to come up with a very efficient way of storing rdata, but at the same
28  * time allow it to be manipulated.
29  *
30  * The decision was to store rdata in uncompressed wire format,
31  * and not to make it a fully abstracted object; i.e. certain parts of the
32  * server know rdata is stored that way.  This saves a lot of memory, and
33  * makes adding rdata to messages easy.  Having much of the server know
34  * the representation would be perilous, and we certainly don't want each
35  * user of rdata to be manipulating such a low-level structure.  This is
36  * where the rdata module comes in.  The module allows rdata handles to be
37  * created and attached to uncompressed wire format regions.  All rdata
38  * operations and conversions are done through these handles.
39  *
40  * Implementation Notes:
41  *
42  *\li	The routines in this module are expected to be synthesized by the
43  *	build process from a set of source files, one per rdata type.  For
44  *	portability, it's probably best that the building be done by a C
45  *	program.  Adding a new rdata type will be a simple matter of adding
46  *	a file to a directory and rebuilding the server.  *All* knowledge of
47  *	the format of a particular rdata type is in this file.
48  *
49  * MP:
50  *\li	Clients of this module must impose any required synchronization.
51  *
52  * Reliability:
53  *\li	This module deals with low-level byte streams.  Errors in any of
54  *	the functions are likely to crash the server or corrupt memory.
55  *
56  *\li	Rdata is typed, and the caller must know what type of rdata it has.
57  *	A caller that gets this wrong could crash the server.
58  *
59  *\li	The fromstruct() and tostruct() routines use a void * pointer to
60  *	represent the structure.  The caller must ensure that it passes a
61  *	pointer to the appropriate type, or the server could crash or memory
62  *	could be corrupted.
63  *
64  * Resources:
65  *\li	None.
66  *
67  * Security:
68  *
69  *\li	*** WARNING ***
70  *	dns_rdata_fromwire() deals with raw network data.  An error in
71  *	this routine could result in the failure or hijacking of the server.
72  *
73  * Standards:
74  *\li	RFC1035
75  *\li	Draft EDNS0 (0)
76  *\li	Draft EDNS1 (0)
77  *\li	Draft Binary Labels (2)
78  *\li	Draft Local Compression (1)
79  *\li	Various RFCs for particular types; these will be documented in the
80  *	 sources files of the types.
81  *
82  */
83 
84 /***
85  *** Imports
86  ***/
87 
88 #include <stdbool.h>
89 
90 #include <isc/lang.h>
91 
92 #include <dns/message.h>
93 #include <dns/name.h>
94 #include <dns/types.h>
95 
96 ISC_LANG_BEGINDECLS
97 
98 /***
99  *** Types
100  ***/
101 
102 /*%
103  ***** An 'rdata' is a handle to a binary region.  The handle has an RR
104  ***** class and type, and the data in the binary region is in the format
105  ***** of the given class and type.
106  *****/
107 /*%
108  * Clients are strongly discouraged from using this type directly, with
109  * the exception of the 'link' field which may be used directly for whatever
110  * purpose the client desires.
111  */
112 struct dns_rdata {
113 	unsigned char   *data;
114 	unsigned int	 length;
115 	dns_rdataclass_t rdclass;
116 	dns_rdatatype_t	 type;
117 	unsigned int	 flags;
118 	ISC_LINK(dns_rdata_t) link;
119 };
120 
121 #define DNS_RDATA_INIT                                           \
122 	{                                                        \
123 		NULL, 0, 0, 0, 0, { (void *)(-1), (void *)(-1) } \
124 	}
125 
126 #define DNS_RDATA_CHECKINITIALIZED
127 #ifdef DNS_RDATA_CHECKINITIALIZED
128 #define DNS_RDATA_INITIALIZED(rdata)                                           \
129 	((rdata)->data == NULL && (rdata)->length == 0 &&                      \
130 	 (rdata)->rdclass == 0 && (rdata)->type == 0 && (rdata)->flags == 0 && \
131 	 !ISC_LINK_LINKED((rdata), link))
132 #else /* ifdef DNS_RDATA_CHECKINITIALIZED */
133 #ifdef ISC_LIST_CHECKINIT
134 #define DNS_RDATA_INITIALIZED(rdata) (!ISC_LINK_LINKED((rdata), link))
135 #else /* ifdef ISC_LIST_CHECKINIT */
136 #define DNS_RDATA_INITIALIZED(rdata) true
137 #endif /* ifdef ISC_LIST_CHECKINIT */
138 #endif /* ifdef DNS_RDATA_CHECKINITIALIZED */
139 
140 #define DNS_RDATA_UPDATE  0x0001 /*%< update pseudo record. */
141 #define DNS_RDATA_OFFLINE 0x0002 /*%< RRSIG has a offline key. */
142 
143 #define DNS_RDATA_VALIDFLAGS(rdata) \
144 	(((rdata)->flags & ~(DNS_RDATA_UPDATE | DNS_RDATA_OFFLINE)) == 0)
145 
146 /*
147  * The maximum length of a RDATA that can be sent on the wire.
148  * Max packet size (65535) less header (12), less name (1), type (2),
149  * class (2), ttl(4), length (2).
150  *
151  * None of the defined types that support name compression can exceed
152  * this and all new types are to be sent uncompressed.
153  */
154 
155 #define DNS_RDATA_MAXLENGTH 65512U
156 
157 /*
158  * Flags affecting rdata formatting style.  Flags 0xFFFF0000
159  * are used by masterfile-level formatting and defined elsewhere.
160  * See additional comments at dns_rdata_tofmttext().
161  */
162 
163 /*% Split the rdata into multiple lines to try to keep it
164  * within the "width". */
165 #define DNS_STYLEFLAG_MULTILINE 0x00000001ULL
166 
167 /*% Output explanatory comments. */
168 #define DNS_STYLEFLAG_COMMENT	0x00000002ULL
169 #define DNS_STYLEFLAG_RRCOMMENT 0x00000004ULL
170 
171 /*% Output KEYDATA in human readable format. */
172 #define DNS_STYLEFLAG_KEYDATA 0x00000008ULL
173 
174 /*% Output textual RR type and RDATA in RFC 3597 unknown format */
175 #define DNS_STYLEFLAG_UNKNOWNFORMAT 0x00000010ULL
176 
177 /*% Print AAAA record fully expanded */
178 #define DNS_STYLEFLAG_EXPANDAAAA 0x00000020ULL
179 
180 #define DNS_RDATA_DOWNCASE	 DNS_NAME_DOWNCASE
181 #define DNS_RDATA_CHECKNAMES	 DNS_NAME_CHECKNAMES
182 #define DNS_RDATA_CHECKNAMESFAIL DNS_NAME_CHECKNAMESFAIL
183 #define DNS_RDATA_CHECKREVERSE	 DNS_NAME_CHECKREVERSE
184 #define DNS_RDATA_CHECKMX	 DNS_NAME_CHECKMX
185 #define DNS_RDATA_CHECKMXFAIL	 DNS_NAME_CHECKMXFAIL
186 #define DNS_RDATA_UNKNOWNESCAPE	 0x80000000
187 
188 /***
189  *** Initialization
190  ***/
191 
192 void
193 dns_rdata_init(dns_rdata_t *rdata);
194 /*%<
195  * Make 'rdata' empty.
196  *
197  * Requires:
198  *	'rdata' is a valid rdata (i.e. not NULL, points to a struct dns_rdata)
199  */
200 
201 void
202 dns_rdata_reset(dns_rdata_t *rdata);
203 /*%<
204  * Make 'rdata' empty.
205  *
206  * Requires:
207  *\li	'rdata' is a previously initialized rdata and is not linked.
208  */
209 
210 void
211 dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target);
212 /*%<
213  * Clone 'target' from 'src'.
214  *
215  * Requires:
216  *\li	'src' to be initialized.
217  *\li	'target' to be initialized.
218  */
219 
220 /***
221  *** Comparisons
222  ***/
223 
224 int
225 dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2);
226 /*%<
227  * Determine the relative ordering under the DNSSEC order relation of
228  * 'rdata1' and 'rdata2'.
229  *
230  * Requires:
231  *
232  *\li	'rdata1' is a valid, non-empty rdata
233  *
234  *\li	'rdata2' is a valid, non-empty rdata
235  *
236  * Returns:
237  *\li	< 0		'rdata1' is less than 'rdata2'
238  *\li	0		'rdata1' is equal to 'rdata2'
239  *\li	> 0		'rdata1' is greater than 'rdata2'
240  */
241 
242 int
243 dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2);
244 /*%<
245  * dns_rdata_casecompare() is similar to dns_rdata_compare() but also
246  * compares domain names case insensitively in known rdata types that
247  * are treated as opaque data by dns_rdata_compare().
248  *
249  * Requires:
250  *
251  *\li	'rdata1' is a valid, non-empty rdata
252  *
253  *\li	'rdata2' is a valid, non-empty rdata
254  *
255  * Returns:
256  *\li	< 0		'rdata1' is less than 'rdata2'
257  *\li	0		'rdata1' is equal to 'rdata2'
258  *\li	> 0		'rdata1' is greater than 'rdata2'
259  */
260 
261 /***
262  *** Conversions
263  ***/
264 
265 void
266 dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
267 		     dns_rdatatype_t type, isc_region_t *r);
268 /*%<
269  * Make 'rdata' refer to region 'r'.
270  *
271  * Requires:
272  *
273  *\li	The data in 'r' is properly formatted for whatever type it is.
274  */
275 
276 void
277 dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r);
278 /*%<
279  * Make 'r' refer to 'rdata'.
280  */
281 
282 isc_result_t
283 dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
284 		   dns_rdatatype_t type, isc_buffer_t *source,
285 		   dns_decompress_t *dctx, unsigned int options,
286 		   isc_buffer_t *target);
287 /*%<
288  * Copy the possibly-compressed rdata at source into the target region.
289  *
290  * Notes:
291  *\li	Name decompression policy is controlled by 'dctx'.
292  *
293  *	'options'
294  *\li	DNS_RDATA_DOWNCASE	downcase domain names when they are copied
295  *				into target.
296  *
297  * Requires:
298  *
299  *\li	'rdclass' and 'type' are valid.
300  *
301  *\li	'source' is a valid buffer, and the active region of 'source'
302  *	references the rdata to be processed.
303  *
304  *\li	'target' is a valid buffer.
305  *
306  *\li	'dctx' is a valid decompression context.
307  *
308  * Ensures,
309  *	if result is success:
310  *	\li 	If 'rdata' is not NULL, it is attached to the target.
311  *	\li	The conditions dns_name_fromwire() ensures for names hold
312  *		for all names in the rdata.
313  *	\li	The current location in source is advanced, and the used space
314  *		in target is updated.
315  *
316  * Result:
317  *\li	Success
318  *\li	Any non-success status from dns_name_fromwire()
319  *\li	Various 'Bad Form' class failures depending on class and type
320  *\li	Bad Form: Input too short
321  *\li	Resource Limit: Not enough space
322  */
323 
324 isc_result_t
325 dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
326 		 isc_buffer_t *target);
327 /*%<
328  * Convert 'rdata' into wire format, compressing it as specified by the
329  * compression context 'cctx', and storing the result in 'target'.
330  *
331  * Notes:
332  *\li	If the compression context allows global compression, then the
333  *	global compression table may be updated.
334  *
335  * Requires:
336  *\li	'rdata' is a valid, non-empty rdata
337  *
338  *\li	target is a valid buffer
339  *
340  *\li	Any offsets specified in a global compression table are valid
341  *	for target.
342  *
343  * Ensures,
344  *	if the result is success:
345  *	\li	The used space in target is updated.
346  *
347  * Returns:
348  *\li	Success
349  *\li	Any non-success status from dns_name_towire()
350  *\li	Resource Limit: Not enough space
351  */
352 
353 isc_result_t
354 dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
355 		   dns_rdatatype_t type, isc_lex_t *lexer,
356 		   const dns_name_t *origin, unsigned int options,
357 		   isc_mem_t *mctx, isc_buffer_t *target,
358 		   dns_rdatacallbacks_t *callbacks);
359 /*%<
360  * Convert the textual representation of a DNS rdata into uncompressed wire
361  * form stored in the target region.  Tokens constituting the text of the rdata
362  * are taken from 'lexer'.
363  *
364  * Notes:
365  *\li	Relative domain names in the rdata will have 'origin' appended to them.
366  *	A NULL origin implies "origin == dns_rootname".
367  *
368  *
369  *	'options'
370  *\li	DNS_RDATA_DOWNCASE	downcase domain names when they are copied
371  *				into target.
372  *\li	DNS_RDATA_CHECKNAMES 	perform checknames checks.
373  *\li	DNS_RDATA_CHECKNAMESFAIL fail if the checknames check fail.  If
374  *				not set a warning will be issued.
375  *\li	DNS_RDATA_CHECKREVERSE  this should set if the owner name ends
376  *				in IP6.ARPA, IP6.INT or IN-ADDR.ARPA.
377  *
378  * Requires:
379  *
380  *\li	'rdclass' and 'type' are valid.
381  *
382  *\li	'lexer' is a valid isc_lex_t.
383  *
384  *\li	'mctx' is a valid isc_mem_t.
385  *
386  *\li	'target' is a valid region.
387  *
388  *\li	'origin' if non NULL it must be absolute.
389  *
390  *\li	'callbacks' to be NULL or callbacks->warn and callbacks->error be
391  *	initialized.
392  *
393  * Ensures,
394  *	if result is success:
395  *\li	 	If 'rdata' is not NULL, it is attached to the target.
396  *
397  *\li		The conditions dns_name_fromtext() ensures for names hold
398  *		for all names in the rdata.
399  *
400  *\li		The used space in target is updated.
401  *
402  * Result:
403  *\li	Success
404  *\li	Translated result codes from isc_lex_gettoken
405  *\li	Various 'Bad Form' class failures depending on class and type
406  *\li	Bad Form: Input too short
407  *\li	Resource Limit: Not enough space
408  *\li	Resource Limit: Not enough memory
409  */
410 
411 isc_result_t
412 dns_rdata_totext(dns_rdata_t *rdata, const dns_name_t *origin,
413 		 isc_buffer_t *target);
414 /*%<
415  * Convert 'rdata' into text format, storing the result in 'target'.
416  * The text will consist of a single line, with fields separated by
417  * single spaces.
418  *
419  * Notes:
420  *\li	If 'origin' is not NULL, then any names in the rdata that are
421  *	subdomains of 'origin' will be made relative it.
422  *
423  *\li	XXX Do we *really* want to support 'origin'?  I'm inclined towards "no"
424  *	at the moment.
425  *
426  * Requires:
427  *
428  *\li	'rdata' is a valid, non-empty rdata
429  *
430  *\li	'origin' is NULL, or is a valid name
431  *
432  *\li	'target' is a valid text buffer
433  *
434  * Ensures,
435  *	if the result is success:
436  *
437  *	\li	The used space in target is updated.
438  *
439  * Returns:
440  *\li	Success
441  *\li	Any non-success status from dns_name_totext()
442  *\li	Resource Limit: Not enough space
443  */
444 
445 isc_result_t
446 dns_rdata_tofmttext(dns_rdata_t *rdata, const dns_name_t *origin,
447 		    dns_masterstyle_flags_t flags, unsigned int width,
448 		    unsigned int split_width, const char *linebreak,
449 		    isc_buffer_t *target);
450 /*%<
451  * Like dns_rdata_totext, but do formatted output suitable for
452  * database dumps.  This is intended for use by dns_db_dump();
453  * library users are discouraged from calling it directly.
454  *
455  * If (flags & #DNS_STYLEFLAG_MULTILINE) != 0, attempt to stay
456  * within 'width' by breaking the text into multiple lines.
457  * The string 'linebreak' is inserted between lines, and parentheses
458  * are added when necessary.  Because RRs contain unbreakable elements
459  * such as domain names whose length is variable, unpredictable, and
460  * potentially large, there is no guarantee that the lines will
461  * not exceed 'width' anyway.
462  *
463  * If (flags & #DNS_STYLEFLAG_MULTILINE) == 0, the rdata is always
464  * printed as a single line, and no parentheses are used.
465  * The 'width' and 'linebreak' arguments are ignored.
466  *
467  * If (flags & #DNS_STYLEFLAG_COMMENT) != 0, output explanatory
468  * comments next to things like the SOA timer fields.  Some
469  * comments (e.g., the SOA ones) are only printed when multiline
470  * output is selected.
471  *
472  * base64 rdata text (e.g., DNSKEY records) will be split into chunks
473  * of 'split_width' characters.  If split_width == 0, the text will
474  * not be split at all.  If split_width == UINT_MAX (0xffffffff), then
475  * it is undefined and falls back to the default value of 'width'
476  */
477 
478 isc_result_t
479 dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
480 		     dns_rdatatype_t type, void *source, isc_buffer_t *target);
481 /*%<
482  * Convert the C structure representation of an rdata into uncompressed wire
483  * format in 'target'.
484  *
485  * XXX  Should we have a 'size' parameter as a sanity check on target?
486  *
487  * Requires:
488  *
489  *\li	'rdclass' and 'type' are valid.
490  *
491  *\li	'source' points to a valid C struct for the class and type.
492  *
493  *\li	'target' is a valid buffer.
494  *
495  *\li	All structure pointers to memory blocks should be NULL if their
496  *	corresponding length values are zero.
497  *
498  * Ensures,
499  *	if result is success:
500  *	\li 	If 'rdata' is not NULL, it is attached to the target.
501  *
502  *	\li	The used space in 'target' is updated.
503  *
504  * Result:
505  *\li	Success
506  *\li	Various 'Bad Form' class failures depending on class and type
507  *\li	Resource Limit: Not enough space
508  */
509 
510 isc_result_t
511 dns_rdata_tostruct(const dns_rdata_t *rdata, void *target, isc_mem_t *mctx);
512 /*%<
513  * Convert an rdata into its C structure representation.
514  *
515  * If 'mctx' is NULL then 'rdata' must persist while 'target' is being used.
516  *
517  * If 'mctx' is non NULL then memory will be allocated if required.
518  *
519  * Requires:
520  *
521  *\li	'rdata' is a valid, non-empty, non-pseudo rdata.
522  *
523  *\li	'target' to point to a valid pointer for the type and class.
524  *
525  * Result:
526  *\li	Success
527  *\li	Resource Limit: Not enough memory
528  */
529 
530 void
531 dns_rdata_freestruct(void *source);
532 /*%<
533  * Free dynamic memory attached to 'source' (if any).
534  *
535  * Requires:
536  *
537  *\li	'source' to point to the structure previously filled in by
538  *	dns_rdata_tostruct().
539  */
540 
541 bool
542 dns_rdatatype_ismeta(dns_rdatatype_t type);
543 /*%<
544  * Return true iff the rdata type 'type' is a meta-type
545  * like ANY or AXFR.
546  */
547 
548 bool
549 dns_rdatatype_issingleton(dns_rdatatype_t type);
550 /*%<
551  * Return true iff the rdata type 'type' is a singleton type,
552  * like CNAME or SOA.
553  *
554  * Requires:
555  * \li	'type' is a valid rdata type.
556  *
557  */
558 
559 bool
560 dns_rdataclass_ismeta(dns_rdataclass_t rdclass);
561 /*%<
562  * Return true iff the rdata class 'rdclass' is a meta-class
563  * like ANY or NONE.
564  */
565 
566 bool
567 dns_rdatatype_isdnssec(dns_rdatatype_t type);
568 /*%<
569  * Return true iff 'type' is one of the DNSSEC
570  * rdata types that may exist alongside a CNAME record.
571  *
572  * Requires:
573  * \li	'type' is a valid rdata type.
574  */
575 
576 bool
577 dns_rdatatype_iszonecutauth(dns_rdatatype_t type);
578 /*%<
579  * Return true iff rdata of type 'type' is considered authoritative
580  * data (not glue) in the NSEC chain when it occurs in the parent zone
581  * at a zone cut.
582  *
583  * Requires:
584  * \li	'type' is a valid rdata type.
585  *
586  */
587 
588 bool
589 dns_rdatatype_isknown(dns_rdatatype_t type);
590 /*%<
591  * Return true iff the rdata type 'type' is known.
592  *
593  * Requires:
594  * \li	'type' is a valid rdata type.
595  *
596  */
597 
598 isc_result_t
599 dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
600 			 void *arg);
601 /*%<
602  * Call 'add' for each name and type from 'rdata' which is subject to
603  * additional section processing.
604  *
605  * Requires:
606  *
607  *\li	'rdata' is a valid, non-empty rdata.
608  *
609  *\li	'add' is a valid dns_additionalfunc_t.
610  *
611  * Ensures:
612  *
613  *\li	If successful, then add() will have been called for each name
614  *	and type subject to additional section processing.
615  *
616  *\li	If add() returns something other than #ISC_R_SUCCESS, that result
617  *	will be returned as the result of dns_rdata_additionaldata().
618  *
619  * Returns:
620  *
621  *\li	ISC_R_SUCCESS
622  *
623  *\li	Many other results are possible if not successful.
624  */
625 
626 isc_result_t
627 dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg);
628 /*%<
629  * Send 'rdata' in DNSSEC canonical form to 'digest'.
630  *
631  * Note:
632  *\li	'digest' may be called more than once by dns_rdata_digest().  The
633  *	concatenation of all the regions, in the order they were given
634  *	to 'digest', will be the DNSSEC canonical form of 'rdata'.
635  *
636  * Requires:
637  *
638  *\li	'rdata' is a valid, non-empty rdata.
639  *
640  *\li	'digest' is a valid dns_digestfunc_t.
641  *
642  * Ensures:
643  *
644  *\li	If successful, then all of the rdata's data has been sent, in
645  *	DNSSEC canonical form, to 'digest'.
646  *
647  *\li	If digest() returns something other than ISC_R_SUCCESS, that result
648  *	will be returned as the result of dns_rdata_digest().
649  *
650  * Returns:
651  *
652  *\li	ISC_R_SUCCESS
653  *
654  *\li	Many other results are possible if not successful.
655  */
656 
657 bool
658 dns_rdatatype_questiononly(dns_rdatatype_t type);
659 /*%<
660  * Return true iff rdata of type 'type' can only appear in the question
661  * section of a properly formatted message.
662  *
663  * Requires:
664  * \li	'type' is a valid rdata type.
665  *
666  */
667 
668 bool
669 dns_rdatatype_notquestion(dns_rdatatype_t type);
670 /*%<
671  * Return true iff rdata of type 'type' can not appear in the question
672  * section of a properly formatted message.
673  *
674  * Requires:
675  * \li	'type' is a valid rdata type.
676  *
677  */
678 
679 bool
680 dns_rdatatype_atparent(dns_rdatatype_t type);
681 /*%<
682  * Return true iff rdata of type 'type' should appear at the parent of
683  * a zone cut.
684  *
685  * Requires:
686  * \li	'type' is a valid rdata type.
687  *
688  */
689 
690 bool
691 dns_rdatatype_atcname(dns_rdatatype_t type);
692 /*%<
693  * Return true iff rdata of type 'type' can appear beside a cname.
694  *
695  * Requires:
696  * \li	'type' is a valid rdata type.
697  *
698  */
699 
700 bool
701 dns_rdatatype_followadditional(dns_rdatatype_t type);
702 /*%<
703  * Return true if adding a record of type 'type' to the ADDITIONAL section
704  * of a message can itself trigger the addition of still more data to the
705  * additional section.
706  *
707  * (For example: adding SRV to the ADDITIONAL section may trigger
708  * the addition of address records associated with that SRV.)
709  *
710  * Requires:
711  * \li	'type' is a valid rdata type.
712  *
713  */
714 
715 unsigned int
716 dns_rdatatype_attributes(dns_rdatatype_t rdtype);
717 /*%<
718  * Return attributes for the given type.
719  *
720  * Requires:
721  *\li	'rdtype' are known.
722  *
723  * Returns:
724  *\li	a bitmask consisting of the following flags.
725  */
726 
727 /*% only one may exist for a name */
728 #define DNS_RDATATYPEATTR_SINGLETON 0x00000001U
729 /*% requires no other data be present */
730 #define DNS_RDATATYPEATTR_EXCLUSIVE 0x00000002U
731 /*% Is a meta type */
732 #define DNS_RDATATYPEATTR_META 0x00000004U
733 /*% Is a DNSSEC type, like RRSIG or NSEC */
734 #define DNS_RDATATYPEATTR_DNSSEC 0x00000008U
735 /*% Is a zone cut authority type */
736 #define DNS_RDATATYPEATTR_ZONECUTAUTH 0x00000010U
737 /*% Is reserved (unusable) */
738 #define DNS_RDATATYPEATTR_RESERVED 0x00000020U
739 /*% Is an unknown type */
740 #define DNS_RDATATYPEATTR_UNKNOWN 0x00000040U
741 /*% Is META, and can only be in a question section */
742 #define DNS_RDATATYPEATTR_QUESTIONONLY 0x00000080U
743 /*% Is META, and can NOT be in a question section */
744 #define DNS_RDATATYPEATTR_NOTQUESTION 0x00000100U
745 /*% Is present at zone cuts in the parent, not the child */
746 #define DNS_RDATATYPEATTR_ATPARENT 0x00000200U
747 /*% Can exist along side a CNAME */
748 #define DNS_RDATATYPEATTR_ATCNAME 0x00000400U
749 /*% Follow additional */
750 #define DNS_RDATATYPEATTR_FOLLOWADDITIONAL 0x00000800U
751 
752 dns_rdatatype_t
753 dns_rdata_covers(dns_rdata_t *rdata);
754 /*%<
755  * Return the rdatatype that this type covers.
756  *
757  * Requires:
758  *\li	'rdata' is a valid, non-empty rdata.
759  *
760  *\li	'rdata' is a type that covers other rdata types.
761  *
762  * Returns:
763  *\li	The type covered.
764  */
765 
766 bool
767 dns_rdata_checkowner(const dns_name_t *name, dns_rdataclass_t rdclass,
768 		     dns_rdatatype_t type, bool wildcard);
769 /*
770  * Returns whether this is a valid ownername for this <type,class>.
771  * If wildcard is true allow the first label to be a wildcard if
772  * appropriate.
773  *
774  * Requires:
775  *	'name' is a valid name.
776  */
777 
778 bool
779 dns_rdata_checknames(dns_rdata_t *rdata, const dns_name_t *owner,
780 		     dns_name_t *bad);
781 /*
782  * Returns whether 'rdata' contains valid domain names.  The checks are
783  * sensitive to the owner name.
784  *
785  * If 'bad' is non-NULL and a domain name fails the check the
786  * the offending name will be return in 'bad' by cloning from
787  * the 'rdata' contents.
788  *
789  * Requires:
790  *	'rdata' to be valid.
791  *	'owner' to be valid.
792  *	'bad'	to be NULL or valid.
793  */
794 
795 void
796 dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type);
797 
798 void
799 dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type);
800 
801 void
802 dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type);
803 
804 void
805 dns_rdata_makedelete(dns_rdata_t *rdata);
806 
807 const char *
808 dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section);
809 
810 ISC_LANG_ENDDECLS
811 
812 #endif /* DNS_RDATA_H */
813