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
99typedef 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
105typedef struct dns_rdata_cname {
106	dns_rdatacommon_t	common;
107	dns_name_t		cname;
108} dns_rdata_cname_t;
109
110typedef struct dns_rdata_ns {
111	dns_rdatacommon_t	common;
112	dns_name_t		name;
113} dns_rdata_ns_t;
114
115typedef 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
126typedef 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 */
149struct 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
214void
215dns_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
223void
224dns_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
232void
233dns_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
246void
247dns_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
257void
258dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r);
259/*%<
260 * Make 'r' refer to 'rdata'.
261 */
262
263isc_result_t
264dns_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
305isc_result_t
306dns_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
334isc_result_t
335dns_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
367isc_result_t
368dns_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
399isc_result_t
400dns_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
432isc_result_t
433dns_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
465isc_result_t
466dns_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
482isc_result_t
483dns_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
499isc_result_t
500dns_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
516isc_result_t
517dns_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
533void
534dns_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
544void
545dns_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
555void
556dns_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
566void
567dns_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
577unsigned int
578dns_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
594dns_rdatatype_t
595dns_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
608int
609dns_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