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