]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - contrib/bind9/lib/dns/rdata.c
Fix multiple Denial of Service vulnerabilities with named(8).
[FreeBSD/releng/9.0.git] / contrib / bind9 / lib / dns / rdata.c
1 /*
2  * Copyright (C) 2004-2011  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1998-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /* $Id: rdata.c,v 1.209.8.2 2011-03-11 06:47:05 marka Exp $ */
19
20 /*! \file */
21
22 #include <config.h>
23 #include <ctype.h>
24
25 #include <isc/base64.h>
26 #include <isc/hex.h>
27 #include <isc/lex.h>
28 #include <isc/mem.h>
29 #include <isc/parseint.h>
30 #include <isc/print.h>
31 #include <isc/string.h>
32 #include <isc/stdlib.h>
33 #include <isc/util.h>
34
35 #include <dns/callbacks.h>
36 #include <dns/cert.h>
37 #include <dns/compress.h>
38 #include <dns/enumtype.h>
39 #include <dns/keyflags.h>
40 #include <dns/keyvalues.h>
41 #include <dns/message.h>
42 #include <dns/rcode.h>
43 #include <dns/rdata.h>
44 #include <dns/rdataclass.h>
45 #include <dns/rdatastruct.h>
46 #include <dns/rdatatype.h>
47 #include <dns/result.h>
48 #include <dns/secalg.h>
49 #include <dns/secproto.h>
50 #include <dns/time.h>
51 #include <dns/ttl.h>
52
53 #define RETERR(x) \
54         do { \
55                 isc_result_t _r = (x); \
56                 if (_r != ISC_R_SUCCESS) \
57                         return (_r); \
58         } while (0)
59
60 #define RETTOK(x) \
61         do { \
62                 isc_result_t _r = (x); \
63                 if (_r != ISC_R_SUCCESS) { \
64                         isc_lex_ungettoken(lexer, &token); \
65                         return (_r); \
66                 } \
67         } while (0)
68
69 #define DNS_AS_STR(t) ((t).value.as_textregion.base)
70
71 #define ARGS_FROMTEXT   int rdclass, dns_rdatatype_t type, \
72                         isc_lex_t *lexer, dns_name_t *origin, \
73                         unsigned int options, isc_buffer_t *target, \
74                         dns_rdatacallbacks_t *callbacks
75
76 #define ARGS_TOTEXT     dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, \
77                         isc_buffer_t *target
78
79 #define ARGS_FROMWIRE   int rdclass, dns_rdatatype_t type, \
80                         isc_buffer_t *source, dns_decompress_t *dctx, \
81                         unsigned int options, isc_buffer_t *target
82
83 #define ARGS_TOWIRE     dns_rdata_t *rdata, dns_compress_t *cctx, \
84                         isc_buffer_t *target
85
86 #define ARGS_COMPARE    const dns_rdata_t *rdata1, const dns_rdata_t *rdata2
87
88 #define ARGS_FROMSTRUCT int rdclass, dns_rdatatype_t type, \
89                         void *source, isc_buffer_t *target
90
91 #define ARGS_TOSTRUCT   dns_rdata_t *rdata, void *target, isc_mem_t *mctx
92
93 #define ARGS_FREESTRUCT void *source
94
95 #define ARGS_ADDLDATA   dns_rdata_t *rdata, dns_additionaldatafunc_t add, \
96                         void *arg
97
98 #define ARGS_DIGEST     dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg
99
100 #define ARGS_CHECKOWNER dns_name_t *name, dns_rdataclass_t rdclass, \
101                         dns_rdatatype_t type, isc_boolean_t wildcard
102
103 #define ARGS_CHECKNAMES dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad
104
105
106 /*%
107  * Context structure for the totext_ functions.
108  * Contains formatting options for rdata-to-text
109  * conversion.
110  */
111 typedef struct dns_rdata_textctx {
112         dns_name_t *origin;     /*%< Current origin, or NULL. */
113         unsigned int flags;     /*%< DNS_STYLEFLAG_*  */
114         unsigned int width;     /*%< Width of rdata column. */
115         const char *linebreak;  /*%< Line break string. */
116 } dns_rdata_textctx_t;
117
118 static isc_result_t
119 txt_totext(isc_region_t *source, isc_buffer_t *target);
120
121 static isc_result_t
122 txt_fromtext(isc_textregion_t *source, isc_buffer_t *target);
123
124 static isc_result_t
125 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
126
127 static isc_boolean_t
128 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target);
129
130 static unsigned int
131 name_length(dns_name_t *name);
132
133 static isc_result_t
134 str_totext(const char *source, isc_buffer_t *target);
135
136 static isc_result_t
137 inet_totext(int af, isc_region_t *src, isc_buffer_t *target);
138
139 static isc_boolean_t
140 buffer_empty(isc_buffer_t *source);
141
142 static void
143 buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region);
144
145 static isc_result_t
146 uint32_tobuffer(isc_uint32_t, isc_buffer_t *target);
147
148 static isc_result_t
149 uint16_tobuffer(isc_uint32_t, isc_buffer_t *target);
150
151 static isc_result_t
152 uint8_tobuffer(isc_uint32_t, isc_buffer_t *target);
153
154 static isc_result_t
155 name_tobuffer(dns_name_t *name, isc_buffer_t *target);
156
157 static isc_uint32_t
158 uint32_fromregion(isc_region_t *region);
159
160 static isc_uint16_t
161 uint16_fromregion(isc_region_t *region);
162
163 static isc_uint8_t
164 uint8_fromregion(isc_region_t *region);
165
166 static isc_uint8_t
167 uint8_consume_fromregion(isc_region_t *region);
168
169 static isc_result_t
170 mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
171
172 static int
173 hexvalue(char value);
174
175 static int
176 decvalue(char value);
177
178 static isc_result_t
179 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target);
180
181 static isc_result_t
182 atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target);
183
184 static void
185 default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *, ...)
186      ISC_FORMAT_PRINTF(2, 3);
187
188 static void
189 fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
190                dns_rdatacallbacks_t *callbacks, const char *name,
191                unsigned long line, isc_token_t *token, isc_result_t result);
192
193 static void
194 fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks);
195
196 static isc_result_t
197 rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
198              isc_buffer_t *target);
199
200 static void
201 warn_badname(dns_name_t *name, isc_lex_t *lexer,
202              dns_rdatacallbacks_t *callbacks);
203
204 static void
205 warn_badmx(isc_token_t *token, isc_lex_t *lexer,
206            dns_rdatacallbacks_t *callbacks);
207
208 static isc_uint16_t
209 uint16_consume_fromregion(isc_region_t *region);
210
211 static inline int
212 getquad(const void *src, struct in_addr *dst,
213         isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks)
214 {
215         int result;
216         struct in_addr *tmp;
217
218         result = inet_aton(src, dst);
219         if (result == 1 && callbacks != NULL &&
220             inet_pton(AF_INET, src, &tmp) != 1) {
221                 const char *name = isc_lex_getsourcename(lexer);
222                 if (name == NULL)
223                         name = "UNKNOWN";
224                 (*callbacks->warn)(callbacks, "%s:%lu: \"%s\" "
225                                    "is not a decimal dotted quad", name,
226                                    isc_lex_getsourceline(lexer), src);
227         }
228         return (result);
229 }
230
231 static inline isc_result_t
232 name_duporclone(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) {
233
234         if (mctx != NULL)
235                 return (dns_name_dup(source, mctx, target));
236         dns_name_clone(source, target);
237         return (ISC_R_SUCCESS);
238 }
239
240 static inline void *
241 mem_maybedup(isc_mem_t *mctx, void *source, size_t length) {
242         void *new;
243
244         if (mctx == NULL)
245                 return (source);
246         new = isc_mem_allocate(mctx, length);
247         if (new != NULL)
248                 memcpy(new, source, length);
249
250         return (new);
251 }
252
253 static const char hexdigits[] = "0123456789abcdef";
254 static const char decdigits[] = "0123456789";
255
256 #include "code.h"
257
258 #define META 0x0001
259 #define RESERVED 0x0002
260
261 /***
262  *** Initialization
263  ***/
264
265 void
266 dns_rdata_init(dns_rdata_t *rdata) {
267
268         REQUIRE(rdata != NULL);
269
270         rdata->data = NULL;
271         rdata->length = 0;
272         rdata->rdclass = 0;
273         rdata->type = 0;
274         rdata->flags = 0;
275         ISC_LINK_INIT(rdata, link);
276         /* ISC_LIST_INIT(rdata->list); */
277 }
278
279 void
280 dns_rdata_reset(dns_rdata_t *rdata) {
281
282         REQUIRE(rdata != NULL);
283
284         REQUIRE(!ISC_LINK_LINKED(rdata, link));
285         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
286
287         rdata->data = NULL;
288         rdata->length = 0;
289         rdata->rdclass = 0;
290         rdata->type = 0;
291         rdata->flags = 0;
292 }
293
294 /***
295  ***
296  ***/
297
298 void
299 dns_rdata_clone(const dns_rdata_t *src, dns_rdata_t *target) {
300
301         REQUIRE(src != NULL);
302         REQUIRE(target != NULL);
303
304         REQUIRE(DNS_RDATA_INITIALIZED(target));
305
306         REQUIRE(DNS_RDATA_VALIDFLAGS(src));
307         REQUIRE(DNS_RDATA_VALIDFLAGS(target));
308
309         target->data = src->data;
310         target->length = src->length;
311         target->rdclass = src->rdclass;
312         target->type = src->type;
313         target->flags = src->flags;
314 }
315
316
317 /***
318  *** Comparisons
319  ***/
320
321 int
322 dns_rdata_compare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) {
323         int result = 0;
324         isc_boolean_t use_default = ISC_FALSE;
325
326         REQUIRE(rdata1 != NULL);
327         REQUIRE(rdata2 != NULL);
328         REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
329         REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
330         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
331         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
332
333         if (rdata1->rdclass != rdata2->rdclass)
334                 return (rdata1->rdclass < rdata2->rdclass ? -1 : 1);
335
336         if (rdata1->type != rdata2->type)
337                 return (rdata1->type < rdata2->type ? -1 : 1);
338
339         COMPARESWITCH
340
341         if (use_default) {
342                 isc_region_t r1;
343                 isc_region_t r2;
344
345                 dns_rdata_toregion(rdata1, &r1);
346                 dns_rdata_toregion(rdata2, &r2);
347                 result = isc_region_compare(&r1, &r2);
348         }
349         return (result);
350 }
351
352 int
353 dns_rdata_casecompare(const dns_rdata_t *rdata1, const dns_rdata_t *rdata2) {
354         int result = 0;
355         isc_boolean_t use_default = ISC_FALSE;
356
357         REQUIRE(rdata1 != NULL);
358         REQUIRE(rdata2 != NULL);
359         REQUIRE(rdata1->length == 0 || rdata1->data != NULL);
360         REQUIRE(rdata2->length == 0 || rdata2->data != NULL);
361         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata1));
362         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata2));
363
364         if (rdata1->rdclass != rdata2->rdclass)
365                 return (rdata1->rdclass < rdata2->rdclass ? -1 : 1);
366
367         if (rdata1->type != rdata2->type)
368                 return (rdata1->type < rdata2->type ? -1 : 1);
369
370         CASECOMPARESWITCH
371
372         if (use_default) {
373                 isc_region_t r1;
374                 isc_region_t r2;
375
376                 dns_rdata_toregion(rdata1, &r1);
377                 dns_rdata_toregion(rdata2, &r2);
378                 result = isc_region_compare(&r1, &r2);
379         }
380         return (result);
381 }
382
383 /***
384  *** Conversions
385  ***/
386
387 void
388 dns_rdata_fromregion(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
389                      dns_rdatatype_t type, isc_region_t *r)
390 {
391
392         REQUIRE(rdata != NULL);
393         REQUIRE(DNS_RDATA_INITIALIZED(rdata));
394         REQUIRE(r != NULL);
395
396         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
397
398         rdata->data = r->base;
399         rdata->length = r->length;
400         rdata->rdclass = rdclass;
401         rdata->type = type;
402         rdata->flags = 0;
403 }
404
405 void
406 dns_rdata_toregion(const dns_rdata_t *rdata, isc_region_t *r) {
407
408         REQUIRE(rdata != NULL);
409         REQUIRE(r != NULL);
410         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
411
412         r->base = rdata->data;
413         r->length = rdata->length;
414 }
415
416 isc_result_t
417 dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
418                    dns_rdatatype_t type, isc_buffer_t *source,
419                    dns_decompress_t *dctx, unsigned int options,
420                    isc_buffer_t *target)
421 {
422         isc_result_t result = ISC_R_NOTIMPLEMENTED;
423         isc_region_t region;
424         isc_buffer_t ss;
425         isc_buffer_t st;
426         isc_boolean_t use_default = ISC_FALSE;
427         isc_uint32_t activelength;
428         size_t length;
429
430         REQUIRE(dctx != NULL);
431         if (rdata != NULL) {
432                 REQUIRE(DNS_RDATA_INITIALIZED(rdata));
433                 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
434         }
435
436         if (type == 0)
437                 return (DNS_R_FORMERR);
438
439         ss = *source;
440         st = *target;
441
442         activelength = isc_buffer_activelength(source);
443         INSIST(activelength < 65536);
444
445         FROMWIRESWITCH
446
447         if (use_default) {
448                 if (activelength > isc_buffer_availablelength(target))
449                         result = ISC_R_NOSPACE;
450                 else {
451                         isc_buffer_putmem(target, isc_buffer_current(source),
452                                           activelength);
453                         isc_buffer_forward(source, activelength);
454                         result = ISC_R_SUCCESS;
455                 }
456         }
457
458         /*
459          * Reject any rdata that expands out to more than DNS_RDATA_MAXLENGTH
460          * as we cannot transmit it.
461          */
462         length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
463         if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
464                 result = DNS_R_FORMERR;
465
466         /*
467          * We should have consumed all of our buffer.
468          */
469         if (result == ISC_R_SUCCESS && !buffer_empty(source))
470                 result = DNS_R_EXTRADATA;
471
472         if (rdata != NULL && result == ISC_R_SUCCESS) {
473                 region.base = isc_buffer_used(&st);
474                 region.length = length;
475                 dns_rdata_fromregion(rdata, rdclass, type, &region);
476         }
477
478         if (result != ISC_R_SUCCESS) {
479                 *source = ss;
480                 *target = st;
481         }
482         return (result);
483 }
484
485 isc_result_t
486 dns_rdata_towire(dns_rdata_t *rdata, dns_compress_t *cctx,
487                  isc_buffer_t *target)
488 {
489         isc_result_t result = ISC_R_NOTIMPLEMENTED;
490         isc_boolean_t use_default = ISC_FALSE;
491         isc_region_t tr;
492         isc_buffer_t st;
493
494         REQUIRE(rdata != NULL);
495         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
496
497         /*
498          * Some DynDNS meta-RRs have empty rdata.
499          */
500         if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
501                 INSIST(rdata->length == 0);
502                 return (ISC_R_SUCCESS);
503         }
504
505         st = *target;
506
507         TOWIRESWITCH
508
509         if (use_default) {
510                 isc_buffer_availableregion(target, &tr);
511                 if (tr.length < rdata->length)
512                         return (ISC_R_NOSPACE);
513                 memcpy(tr.base, rdata->data, rdata->length);
514                 isc_buffer_add(target, rdata->length);
515                 return (ISC_R_SUCCESS);
516         }
517         if (result != ISC_R_SUCCESS) {
518                 *target = st;
519                 INSIST(target->used < 65536);
520                 dns_compress_rollback(cctx, (isc_uint16_t)target->used);
521         }
522         return (result);
523 }
524
525 /*
526  * If the binary data in 'src' is valid uncompressed wire format
527  * rdata of class 'rdclass' and type 'type', return ISC_R_SUCCESS
528  * and copy the validated rdata to 'dest'.  Otherwise return an error.
529  */
530 static isc_result_t
531 rdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass,
532             dns_rdatatype_t type)
533 {
534         dns_decompress_t dctx;
535         dns_rdata_t rdata = DNS_RDATA_INIT;
536         isc_result_t result;
537
538         dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
539         isc_buffer_setactive(src, isc_buffer_usedlength(src));
540         result = dns_rdata_fromwire(&rdata, rdclass, type, src,
541                                     &dctx, 0, dest);
542         dns_decompress_invalidate(&dctx);
543
544         return (result);
545 }
546
547 static isc_result_t
548 unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type,
549                  isc_lex_t *lexer, isc_mem_t *mctx, isc_buffer_t *target)
550 {
551         isc_result_t result;
552         isc_buffer_t *buf = NULL;
553         isc_token_t token;
554
555         if (type == 0 || dns_rdatatype_ismeta(type))
556                 return (DNS_R_METATYPE);
557
558         result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
559                                         ISC_FALSE);
560         if (result == ISC_R_SUCCESS && token.value.as_ulong > 65535U)
561                 return (ISC_R_RANGE);
562         result = isc_buffer_allocate(mctx, &buf, token.value.as_ulong);
563         if (result != ISC_R_SUCCESS)
564                 return (result);
565
566         result = isc_hex_tobuffer(lexer, buf,
567                                   (unsigned int)token.value.as_ulong);
568         if (result != ISC_R_SUCCESS)
569                goto failure;
570         if (isc_buffer_usedlength(buf) != token.value.as_ulong) {
571                 result = ISC_R_UNEXPECTEDEND;
572                 goto failure;
573         }
574
575         if (dns_rdatatype_isknown(type)) {
576                 result = rdata_validate(buf, target, rdclass, type);
577         } else {
578                 isc_region_t r;
579                 isc_buffer_usedregion(buf, &r);
580                 result = isc_buffer_copyregion(target, &r);
581         }
582         if (result != ISC_R_SUCCESS)
583                 goto failure;
584
585         isc_buffer_free(&buf);
586         return (ISC_R_SUCCESS);
587
588  failure:
589         isc_buffer_free(&buf);
590         return (result);
591 }
592
593 isc_result_t
594 dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
595                    dns_rdatatype_t type, isc_lex_t *lexer,
596                    dns_name_t *origin, unsigned int options, isc_mem_t *mctx,
597                    isc_buffer_t *target, dns_rdatacallbacks_t *callbacks)
598 {
599         isc_result_t result = ISC_R_NOTIMPLEMENTED;
600         isc_region_t region;
601         isc_buffer_t st;
602         isc_token_t token;
603         unsigned int lexoptions = ISC_LEXOPT_EOL | ISC_LEXOPT_EOF |
604                                   ISC_LEXOPT_DNSMULTILINE | ISC_LEXOPT_ESCAPE;
605         char *name;
606         unsigned long line;
607         void (*callback)(dns_rdatacallbacks_t *, const char *, ...);
608         isc_result_t tresult;
609         size_t length;
610
611         REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE);
612         if (rdata != NULL) {
613                 REQUIRE(DNS_RDATA_INITIALIZED(rdata));
614                 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
615         }
616         if (callbacks != NULL) {
617                 REQUIRE(callbacks->warn != NULL);
618                 REQUIRE(callbacks->error != NULL);
619         }
620
621         st = *target;
622
623         if (callbacks != NULL)
624                 callback = callbacks->error;
625         else
626                 callback = default_fromtext_callback;
627
628         result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
629                                         ISC_FALSE);
630         if (result != ISC_R_SUCCESS) {
631                 name = isc_lex_getsourcename(lexer);
632                 line = isc_lex_getsourceline(lexer);
633                 fromtext_error(callback, callbacks, name, line,
634                                &token, result);
635                 return (result);
636         }
637
638         if (strcmp(DNS_AS_STR(token), "\\#") == 0)
639                 result = unknown_fromtext(rdclass, type, lexer, mctx, target);
640         else {
641                 isc_lex_ungettoken(lexer, &token);
642
643                 FROMTEXTSWITCH
644         }
645
646         /*
647          * Consume to end of line / file.
648          * If not at end of line initially set error code.
649          * Call callback via fromtext_error once if there was an error.
650          */
651         do {
652                 name = isc_lex_getsourcename(lexer);
653                 line = isc_lex_getsourceline(lexer);
654                 tresult = isc_lex_gettoken(lexer, lexoptions, &token);
655                 if (tresult != ISC_R_SUCCESS) {
656                         if (result == ISC_R_SUCCESS)
657                                 result = tresult;
658                         if (callback != NULL)
659                                 fromtext_error(callback, callbacks, name,
660                                                line, NULL, result);
661                         break;
662                 } else if (token.type != isc_tokentype_eol &&
663                            token.type != isc_tokentype_eof) {
664                         if (result == ISC_R_SUCCESS)
665                                 result = DNS_R_EXTRATOKEN;
666                         if (callback != NULL) {
667                                 fromtext_error(callback, callbacks, name,
668                                                line, &token, result);
669                                 callback = NULL;
670                         }
671                 } else if (result != ISC_R_SUCCESS && callback != NULL) {
672                         fromtext_error(callback, callbacks, name, line,
673                                        &token, result);
674                         break;
675                 } else {
676                         if (token.type == isc_tokentype_eof)
677                                 fromtext_warneof(lexer, callbacks);
678                         break;
679                 }
680         } while (1);
681
682         length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
683         if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
684                 result = ISC_R_NOSPACE;
685
686         if (rdata != NULL && result == ISC_R_SUCCESS) {
687                 region.base = isc_buffer_used(&st);
688                 region.length = length;
689                 dns_rdata_fromregion(rdata, rdclass, type, &region);
690         }
691         if (result != ISC_R_SUCCESS) {
692                 *target = st;
693         }
694         return (result);
695 }
696
697 static isc_result_t
698 rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
699              isc_buffer_t *target)
700 {
701         isc_result_t result = ISC_R_NOTIMPLEMENTED;
702         isc_boolean_t use_default = ISC_FALSE;
703         char buf[sizeof("65535")];
704         isc_region_t sr;
705
706         REQUIRE(rdata != NULL);
707         REQUIRE(tctx->origin == NULL ||
708                 dns_name_isabsolute(tctx->origin) == ISC_TRUE);
709
710         /*
711          * Some DynDNS meta-RRs have empty rdata.
712          */
713         if ((rdata->flags & DNS_RDATA_UPDATE) != 0) {
714                 INSIST(rdata->length == 0);
715                 return (ISC_R_SUCCESS);
716         }
717
718         TOTEXTSWITCH
719
720         if (use_default) {
721                 strlcpy(buf, "\\# ", sizeof(buf));
722                 result = str_totext(buf, target);
723                 INSIST(result == ISC_R_SUCCESS);
724                 dns_rdata_toregion(rdata, &sr);
725                 INSIST(sr.length < 65536);
726                 snprintf(buf, sizeof(buf), "%u", sr.length);
727                 result = str_totext(buf, target);
728                 if (sr.length != 0 && result == ISC_R_SUCCESS) {
729                         if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
730                                 result = str_totext(" ( ", target);
731                         else
732                                 result = str_totext(" ", target);
733                         if (result == ISC_R_SUCCESS)
734                                 result = isc_hex_totext(&sr, tctx->width - 2,
735                                                         tctx->linebreak,
736                                                         target);
737                         if (result == ISC_R_SUCCESS &&
738                             (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
739                                 result = str_totext(" )", target);
740                 }
741         }
742
743         return (result);
744 }
745
746 isc_result_t
747 dns_rdata_totext(dns_rdata_t *rdata, dns_name_t *origin, isc_buffer_t *target)
748 {
749         dns_rdata_textctx_t tctx;
750
751         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
752
753         /*
754          * Set up formatting options for single-line output.
755          */
756         tctx.origin = origin;
757         tctx.flags = 0;
758         tctx.width = 60;
759         tctx.linebreak = " ";
760         return (rdata_totext(rdata, &tctx, target));
761 }
762
763 isc_result_t
764 dns_rdata_tofmttext(dns_rdata_t *rdata, dns_name_t *origin,
765                     unsigned int flags, unsigned int width,
766                     const char *linebreak, isc_buffer_t *target)
767 {
768         dns_rdata_textctx_t tctx;
769
770         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
771
772         /*
773          * Set up formatting options for formatted output.
774          */
775         tctx.origin = origin;
776         tctx.flags = flags;
777         if ((flags & DNS_STYLEFLAG_MULTILINE) != 0) {
778                 tctx.width = width;
779                 tctx.linebreak = linebreak;
780         } else {
781                 tctx.width = 60; /* Used for hex word length only. */
782                 tctx.linebreak = " ";
783         }
784         return (rdata_totext(rdata, &tctx, target));
785 }
786
787 isc_result_t
788 dns_rdata_fromstruct(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
789                      dns_rdatatype_t type, void *source,
790                      isc_buffer_t *target)
791 {
792         isc_result_t result = ISC_R_NOTIMPLEMENTED;
793         isc_buffer_t st;
794         isc_region_t region;
795         isc_boolean_t use_default = ISC_FALSE;
796         size_t length;
797
798         REQUIRE(source != NULL);
799         if (rdata != NULL) {
800                 REQUIRE(DNS_RDATA_INITIALIZED(rdata));
801                 REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
802         }
803
804         st = *target;
805
806         FROMSTRUCTSWITCH
807
808         if (use_default)
809                 (void)NULL;
810
811         length = isc_buffer_usedlength(target) - isc_buffer_usedlength(&st);
812         if (result == ISC_R_SUCCESS && length > DNS_RDATA_MAXLENGTH)
813                 result = ISC_R_NOSPACE;
814
815         if (rdata != NULL && result == ISC_R_SUCCESS) {
816                 region.base = isc_buffer_used(&st);
817                 region.length = length;
818                 dns_rdata_fromregion(rdata, rdclass, type, &region);
819         }
820         if (result != ISC_R_SUCCESS)
821                 *target = st;
822         return (result);
823 }
824
825 isc_result_t
826 dns_rdata_tostruct(dns_rdata_t *rdata, void *target, isc_mem_t *mctx) {
827         isc_result_t result = ISC_R_NOTIMPLEMENTED;
828         isc_boolean_t use_default = ISC_FALSE;
829
830         REQUIRE(rdata != NULL);
831         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
832
833         TOSTRUCTSWITCH
834
835         if (use_default)
836                 (void)NULL;
837
838         return (result);
839 }
840
841 void
842 dns_rdata_freestruct(void *source) {
843         dns_rdatacommon_t *common = source;
844         REQUIRE(source != NULL);
845
846         FREESTRUCTSWITCH
847 }
848
849 isc_result_t
850 dns_rdata_additionaldata(dns_rdata_t *rdata, dns_additionaldatafunc_t add,
851                          void *arg)
852 {
853         isc_result_t result = ISC_R_NOTIMPLEMENTED;
854         isc_boolean_t use_default = ISC_FALSE;
855
856         /*
857          * Call 'add' for each name and type from 'rdata' which is subject to
858          * additional section processing.
859          */
860
861         REQUIRE(rdata != NULL);
862         REQUIRE(add != NULL);
863         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
864
865         ADDITIONALDATASWITCH
866
867         /* No additional processing for unknown types */
868         if (use_default)
869                 result = ISC_R_SUCCESS;
870
871         return (result);
872 }
873
874 isc_result_t
875 dns_rdata_digest(dns_rdata_t *rdata, dns_digestfunc_t digest, void *arg) {
876         isc_result_t result = ISC_R_NOTIMPLEMENTED;
877         isc_boolean_t use_default = ISC_FALSE;
878         isc_region_t r;
879
880         /*
881          * Send 'rdata' in DNSSEC canonical form to 'digest'.
882          */
883
884         REQUIRE(rdata != NULL);
885         REQUIRE(digest != NULL);
886         REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
887
888         DIGESTSWITCH
889
890         if (use_default) {
891                 dns_rdata_toregion(rdata, &r);
892                 result = (digest)(arg, &r);
893         }
894
895         return (result);
896 }
897
898 isc_boolean_t
899 dns_rdata_checkowner(dns_name_t *name, dns_rdataclass_t rdclass,
900                      dns_rdatatype_t type, isc_boolean_t wildcard)
901 {
902         isc_boolean_t result;
903
904         CHECKOWNERSWITCH
905         return (result);
906 }
907
908 isc_boolean_t
909 dns_rdata_checknames(dns_rdata_t *rdata, dns_name_t *owner, dns_name_t *bad)
910 {
911         isc_boolean_t result;
912
913         CHECKNAMESSWITCH
914         return (result);
915 }
916
917 unsigned int
918 dns_rdatatype_attributes(dns_rdatatype_t type)
919 {
920         RDATATYPE_ATTRIBUTE_SW
921         if (type >= (dns_rdatatype_t)128 && type < (dns_rdatatype_t)255)
922                 return (DNS_RDATATYPEATTR_UNKNOWN | DNS_RDATATYPEATTR_META);
923         return (DNS_RDATATYPEATTR_UNKNOWN);
924 }
925
926 isc_result_t
927 dns_rdatatype_fromtext(dns_rdatatype_t *typep, isc_textregion_t *source) {
928         unsigned int hash;
929         unsigned int n;
930         unsigned char a, b;
931
932         n = source->length;
933
934         if (n == 0)
935                 return (DNS_R_UNKNOWN);
936
937         a = tolower((unsigned char)source->base[0]);
938         b = tolower((unsigned char)source->base[n - 1]);
939
940         hash = ((a + n) * b) % 256;
941
942         /*
943          * This switch block is inlined via \#define, and will use "return"
944          * to return a result to the caller if it is a valid (known)
945          * rdatatype name.
946          */
947         RDATATYPE_FROMTEXT_SW(hash, source->base, n, typep);
948
949         if (source->length > 4 && source->length < (4 + sizeof("65000")) &&
950             strncasecmp("type", source->base, 4) == 0) {
951                 char buf[sizeof("65000")];
952                 char *endp;
953                 unsigned int val;
954
955                 strncpy(buf, source->base + 4, source->length - 4);
956                 buf[source->length - 4] = '\0';
957                 val = strtoul(buf, &endp, 10);
958                 if (*endp == '\0' && val <= 0xffff) {
959                         *typep = (dns_rdatatype_t)val;
960                         return (ISC_R_SUCCESS);
961                 }
962         }
963
964         return (DNS_R_UNKNOWN);
965 }
966
967 isc_result_t
968 dns_rdatatype_totext(dns_rdatatype_t type, isc_buffer_t *target) {
969         char buf[sizeof("TYPE65535")];
970
971         RDATATYPE_TOTEXT_SW
972         snprintf(buf, sizeof(buf), "TYPE%u", type);
973         return (str_totext(buf, target));
974 }
975
976 void
977 dns_rdatatype_format(dns_rdatatype_t rdtype,
978                      char *array, unsigned int size)
979 {
980         isc_result_t result;
981         isc_buffer_t buf;
982
983         if (size == 0U)
984                 return;
985
986         isc_buffer_init(&buf, array, size);
987         result = dns_rdatatype_totext(rdtype, &buf);
988         /*
989          * Null terminate.
990          */
991         if (result == ISC_R_SUCCESS) {
992                 if (isc_buffer_availablelength(&buf) >= 1)
993                         isc_buffer_putuint8(&buf, 0);
994                 else
995                         result = ISC_R_NOSPACE;
996         }
997         if (result != ISC_R_SUCCESS)
998                 strlcpy(array, "<unknown>", size);
999 }
1000
1001 /*
1002  * Private function.
1003  */
1004
1005 static unsigned int
1006 name_length(dns_name_t *name) {
1007         return (name->length);
1008 }
1009
1010 static isc_result_t
1011 txt_totext(isc_region_t *source, isc_buffer_t *target) {
1012         unsigned int tl;
1013         unsigned int n;
1014         unsigned char *sp;
1015         char *tp;
1016         isc_region_t region;
1017
1018         isc_buffer_availableregion(target, &region);
1019         sp = source->base;
1020         tp = (char *)region.base;
1021         tl = region.length;
1022
1023         n = *sp++;
1024
1025         REQUIRE(n + 1 <= source->length);
1026
1027         if (tl < 1)
1028                 return (ISC_R_NOSPACE);
1029         *tp++ = '"';
1030         tl--;
1031         while (n--) {
1032                 if (*sp < 0x20 || *sp >= 0x7f) {
1033                         if (tl < 4)
1034                                 return (ISC_R_NOSPACE);
1035                         *tp++ = 0x5c;
1036                         *tp++ = 0x30 + ((*sp / 100) % 10);
1037                         *tp++ = 0x30 + ((*sp / 10) % 10);
1038                         *tp++ = 0x30 + (*sp % 10);
1039                         sp++;
1040                         tl -= 4;
1041                         continue;
1042                 }
1043                 /* double quote, semi-colon, backslash */
1044                 if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) {
1045                         if (tl < 2)
1046                                 return (ISC_R_NOSPACE);
1047                         *tp++ = '\\';
1048                         tl--;
1049                 }
1050                 if (tl < 1)
1051                         return (ISC_R_NOSPACE);
1052                 *tp++ = *sp++;
1053                 tl--;
1054         }
1055         if (tl < 1)
1056                 return (ISC_R_NOSPACE);
1057         *tp++ = '"';
1058         tl--;
1059         isc_buffer_add(target, tp - (char *)region.base);
1060         isc_region_consume(source, *source->base + 1);
1061         return (ISC_R_SUCCESS);
1062 }
1063
1064 static isc_result_t
1065 txt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
1066         isc_region_t tregion;
1067         isc_boolean_t escape;
1068         unsigned int n, nrem;
1069         char *s;
1070         unsigned char *t;
1071         int d;
1072         int c;
1073
1074         isc_buffer_availableregion(target, &tregion);
1075         s = source->base;
1076         n = source->length;
1077         t = tregion.base;
1078         nrem = tregion.length;
1079         escape = ISC_FALSE;
1080         if (nrem < 1)
1081                 return (ISC_R_NOSPACE);
1082         /*
1083          * Length byte.
1084          */
1085         nrem--;
1086         t++;
1087         /*
1088          * Maximum text string length.
1089          */
1090         if (nrem > 255)
1091                 nrem = 255;
1092         while (n-- != 0) {
1093                 c = (*s++) & 0xff;
1094                 if (escape && (d = decvalue((char)c)) != -1) {
1095                         c = d;
1096                         if (n == 0)
1097                                 return (DNS_R_SYNTAX);
1098                         n--;
1099                         if ((d = decvalue(*s++)) != -1)
1100                                 c = c * 10 + d;
1101                         else
1102                                 return (DNS_R_SYNTAX);
1103                         if (n == 0)
1104                                 return (DNS_R_SYNTAX);
1105                         n--;
1106                         if ((d = decvalue(*s++)) != -1)
1107                                 c = c * 10 + d;
1108                         else
1109                                 return (DNS_R_SYNTAX);
1110                         if (c > 255)
1111                                 return (DNS_R_SYNTAX);
1112                 } else if (!escape && c == '\\') {
1113                         escape = ISC_TRUE;
1114                         continue;
1115                 }
1116                 escape = ISC_FALSE;
1117                 if (nrem == 0)
1118                         return (ISC_R_NOSPACE);
1119                 *t++ = c;
1120                 nrem--;
1121         }
1122         if (escape)
1123                 return (DNS_R_SYNTAX);
1124         *tregion.base = t - tregion.base - 1;
1125         isc_buffer_add(target, *tregion.base + 1);
1126         return (ISC_R_SUCCESS);
1127 }
1128
1129 static isc_result_t
1130 txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
1131         unsigned int n;
1132         isc_region_t sregion;
1133         isc_region_t tregion;
1134
1135         isc_buffer_activeregion(source, &sregion);
1136         if (sregion.length == 0)
1137                 return(ISC_R_UNEXPECTEDEND);
1138         n = *sregion.base + 1;
1139         if (n > sregion.length)
1140                 return (ISC_R_UNEXPECTEDEND);
1141
1142         isc_buffer_availableregion(target, &tregion);
1143         if (n > tregion.length)
1144                 return (ISC_R_NOSPACE);
1145
1146         memcpy(tregion.base, sregion.base, n);
1147         isc_buffer_forward(source, n);
1148         isc_buffer_add(target, n);
1149         return (ISC_R_SUCCESS);
1150 }
1151
1152 static isc_boolean_t
1153 name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) {
1154         int l1, l2;
1155
1156         if (origin == NULL)
1157                 goto return_false;
1158
1159         if (dns_name_compare(origin, dns_rootname) == 0)
1160                 goto return_false;
1161
1162         if (!dns_name_issubdomain(name, origin))
1163                 goto return_false;
1164
1165         l1 = dns_name_countlabels(name);
1166         l2 = dns_name_countlabels(origin);
1167
1168         if (l1 == l2)
1169                 goto return_false;
1170
1171         /* Master files should be case preserving. */
1172         dns_name_getlabelsequence(name, l1 - l2, l2, target);
1173         if (!dns_name_caseequal(origin, target))
1174                 goto return_false;
1175
1176         dns_name_getlabelsequence(name, 0, l1 - l2, target);
1177         return (ISC_TRUE);
1178
1179 return_false:
1180         *target = *name;
1181         return (ISC_FALSE);
1182 }
1183
1184 static isc_result_t
1185 str_totext(const char *source, isc_buffer_t *target) {
1186         unsigned int l;
1187         isc_region_t region;
1188
1189         isc_buffer_availableregion(target, &region);
1190         l = strlen(source);
1191
1192         if (l > region.length)
1193                 return (ISC_R_NOSPACE);
1194
1195         memcpy(region.base, source, l);
1196         isc_buffer_add(target, l);
1197         return (ISC_R_SUCCESS);
1198 }
1199
1200 static isc_result_t
1201 inet_totext(int af, isc_region_t *src, isc_buffer_t *target) {
1202         char tmpbuf[64];
1203
1204         /* Note - inet_ntop doesn't do size checking on its input. */
1205         if (inet_ntop(af, src->base, tmpbuf, sizeof(tmpbuf)) == NULL)
1206                 return (ISC_R_NOSPACE);
1207         if (strlen(tmpbuf) > isc_buffer_availablelength(target))
1208                 return (ISC_R_NOSPACE);
1209         isc_buffer_putstr(target, tmpbuf);
1210         return (ISC_R_SUCCESS);
1211 }
1212
1213 static isc_boolean_t
1214 buffer_empty(isc_buffer_t *source) {
1215         return((source->current == source->active) ? ISC_TRUE : ISC_FALSE);
1216 }
1217
1218 static void
1219 buffer_fromregion(isc_buffer_t *buffer, isc_region_t *region) {
1220         isc_buffer_init(buffer, region->base, region->length);
1221         isc_buffer_add(buffer, region->length);
1222         isc_buffer_setactive(buffer, region->length);
1223 }
1224
1225 static isc_result_t
1226 uint32_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
1227         isc_region_t region;
1228
1229         isc_buffer_availableregion(target, &region);
1230         if (region.length < 4)
1231                 return (ISC_R_NOSPACE);
1232         isc_buffer_putuint32(target, value);
1233         return (ISC_R_SUCCESS);
1234 }
1235
1236 static isc_result_t
1237 uint16_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
1238         isc_region_t region;
1239
1240         if (value > 0xffff)
1241                 return (ISC_R_RANGE);
1242         isc_buffer_availableregion(target, &region);
1243         if (region.length < 2)
1244                 return (ISC_R_NOSPACE);
1245         isc_buffer_putuint16(target, (isc_uint16_t)value);
1246         return (ISC_R_SUCCESS);
1247 }
1248
1249 static isc_result_t
1250 uint8_tobuffer(isc_uint32_t value, isc_buffer_t *target) {
1251         isc_region_t region;
1252
1253         if (value > 0xff)
1254                 return (ISC_R_RANGE);
1255         isc_buffer_availableregion(target, &region);
1256         if (region.length < 1)
1257                 return (ISC_R_NOSPACE);
1258         isc_buffer_putuint8(target, (isc_uint8_t)value);
1259         return (ISC_R_SUCCESS);
1260 }
1261
1262 static isc_result_t
1263 name_tobuffer(dns_name_t *name, isc_buffer_t *target) {
1264         isc_region_t r;
1265         dns_name_toregion(name, &r);
1266         return (isc_buffer_copyregion(target, &r));
1267 }
1268
1269 static isc_uint32_t
1270 uint32_fromregion(isc_region_t *region) {
1271         isc_uint32_t value;
1272
1273         REQUIRE(region->length >= 4);
1274         value = region->base[0] << 24;
1275         value |= region->base[1] << 16;
1276         value |= region->base[2] << 8;
1277         value |= region->base[3];
1278         return(value);
1279 }
1280
1281 static isc_uint16_t
1282 uint16_consume_fromregion(isc_region_t *region) {
1283         isc_uint16_t r = uint16_fromregion(region);
1284
1285         isc_region_consume(region, 2);
1286         return r;
1287 }
1288
1289 static isc_uint16_t
1290 uint16_fromregion(isc_region_t *region) {
1291
1292         REQUIRE(region->length >= 2);
1293
1294         return ((region->base[0] << 8) | region->base[1]);
1295 }
1296
1297 static isc_uint8_t
1298 uint8_fromregion(isc_region_t *region) {
1299
1300         REQUIRE(region->length >= 1);
1301
1302         return (region->base[0]);
1303 }
1304
1305 static isc_uint8_t
1306 uint8_consume_fromregion(isc_region_t *region) {
1307         isc_uint8_t r = uint8_fromregion(region);
1308
1309         isc_region_consume(region, 1);
1310         return r;
1311 }
1312
1313 static isc_result_t
1314 mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
1315         isc_region_t tr;
1316
1317         isc_buffer_availableregion(target, &tr);
1318         if (length > tr.length)
1319                 return (ISC_R_NOSPACE);
1320         memcpy(tr.base, base, length);
1321         isc_buffer_add(target, length);
1322         return (ISC_R_SUCCESS);
1323 }
1324
1325 static int
1326 hexvalue(char value) {
1327         char *s;
1328         unsigned char c;
1329
1330         c = (unsigned char)value;
1331
1332         if (!isascii(c))
1333                 return (-1);
1334         if (isupper(c))
1335                 c = tolower(c);
1336         if ((s = strchr(hexdigits, c)) == NULL)
1337                 return (-1);
1338         return (s - hexdigits);
1339 }
1340
1341 static int
1342 decvalue(char value) {
1343         char *s;
1344
1345         /*
1346          * isascii() is valid for full range of int values, no need to
1347          * mask or cast.
1348          */
1349         if (!isascii(value))
1350                 return (-1);
1351         if ((s = strchr(decdigits, value)) == NULL)
1352                 return (-1);
1353         return (s - decdigits);
1354 }
1355
1356 static const char atob_digits[86] =
1357         "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
1358         "abcdefghijklmnopqrstu";
1359 /*
1360  * Subroutines to convert between 8 bit binary bytes and printable ASCII.
1361  * Computes the number of bytes, and three kinds of simple checksums.
1362  * Incoming bytes are collected into 32-bit words, then printed in base 85:
1363  *      exp(85,5) > exp(2,32)
1364  * The ASCII characters used are between '!' and 'u';
1365  * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
1366  *
1367  * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for
1368  * the atob/btoa programs, released with the compress program, in mod.sources.
1369  * Modified by Mike Schwartz 8/19/86 for use in BIND.
1370  * Modified to be re-entrant 3/2/99.
1371  */
1372
1373
1374 struct state {
1375         isc_int32_t Ceor;
1376         isc_int32_t Csum;
1377         isc_int32_t Crot;
1378         isc_int32_t word;
1379         isc_int32_t bcount;
1380 };
1381
1382 #define Ceor state->Ceor
1383 #define Csum state->Csum
1384 #define Crot state->Crot
1385 #define word state->word
1386 #define bcount state->bcount
1387
1388 #define times85(x)      ((((((x<<2)+x)<<2)+x)<<2)+x)
1389
1390 static isc_result_t     byte_atob(int c, isc_buffer_t *target,
1391                                   struct state *state);
1392 static isc_result_t     putbyte(int c, isc_buffer_t *, struct state *state);
1393 static isc_result_t     byte_btoa(int c, isc_buffer_t *, struct state *state);
1394
1395 /*
1396  * Decode ASCII-encoded byte c into binary representation and
1397  * place into *bufp, advancing bufp.
1398  */
1399 static isc_result_t
1400 byte_atob(int c, isc_buffer_t *target, struct state *state) {
1401         char *s;
1402         if (c == 'z') {
1403                 if (bcount != 0)
1404                         return(DNS_R_SYNTAX);
1405                 else {
1406                         RETERR(putbyte(0, target, state));
1407                         RETERR(putbyte(0, target, state));
1408                         RETERR(putbyte(0, target, state));
1409                         RETERR(putbyte(0, target, state));
1410                 }
1411         } else if ((s = strchr(atob_digits, c)) != NULL) {
1412                 if (bcount == 0) {
1413                         word = s - atob_digits;
1414                         ++bcount;
1415                 } else if (bcount < 4) {
1416                         word = times85(word);
1417                         word += s - atob_digits;
1418                         ++bcount;
1419                 } else {
1420                         word = times85(word);
1421                         word += s - atob_digits;
1422                         RETERR(putbyte((word >> 24) & 0xff, target, state));
1423                         RETERR(putbyte((word >> 16) & 0xff, target, state));
1424                         RETERR(putbyte((word >> 8) & 0xff, target, state));
1425                         RETERR(putbyte(word & 0xff, target, state));
1426                         word = 0;
1427                         bcount = 0;
1428                 }
1429         } else
1430                 return(DNS_R_SYNTAX);
1431         return(ISC_R_SUCCESS);
1432 }
1433
1434 /*
1435  * Compute checksum info and place c into target.
1436  */
1437 static isc_result_t
1438 putbyte(int c, isc_buffer_t *target, struct state *state) {
1439         isc_region_t tr;
1440
1441         Ceor ^= c;
1442         Csum += c;
1443         Csum += 1;
1444         if ((Crot & 0x80000000)) {
1445                 Crot <<= 1;
1446                 Crot += 1;
1447         } else {
1448                 Crot <<= 1;
1449         }
1450         Crot += c;
1451         isc_buffer_availableregion(target, &tr);
1452         if (tr.length < 1)
1453                 return (ISC_R_NOSPACE);
1454         tr.base[0] = c;
1455         isc_buffer_add(target, 1);
1456         return (ISC_R_SUCCESS);
1457 }
1458
1459 /*
1460  * Read the ASCII-encoded data from inbuf, of length inbuflen, and convert
1461  * it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes;
1462  * outbuflen must be divisible by 4.  (Note: this is because outbuf is filled
1463  * in 4 bytes at a time.  If the actual data doesn't end on an even 4-byte
1464  * boundary, there will be no problem...it will be padded with 0 bytes, and
1465  * numbytes will indicate the correct number of bytes.  The main point is
1466  * that since the buffer is filled in 4 bytes at a time, even if there is
1467  * not a full 4 bytes of data at the end, there has to be room to 0-pad the
1468  * data, so the buffer must be of size divisible by 4).  Place the number of
1469  * output bytes in numbytes, and return a failure/success status.
1470  */
1471
1472 static isc_result_t
1473 atob_tobuffer(isc_lex_t *lexer, isc_buffer_t *target) {
1474         long oeor, osum, orot;
1475         struct state statebuf, *state= &statebuf;
1476         isc_token_t token;
1477         char c;
1478         char *e;
1479
1480         Ceor = Csum = Crot = word = bcount = 0;
1481
1482         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1483                                       ISC_FALSE));
1484         while (token.value.as_textregion.length != 0) {
1485                 if ((c = token.value.as_textregion.base[0]) == 'x') {
1486                         break;
1487                 } else
1488                         RETERR(byte_atob(c, target, state));
1489                 isc_textregion_consume(&token.value.as_textregion, 1);
1490         }
1491
1492         /*
1493          * Number of bytes.
1494          */
1495         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
1496                                       ISC_FALSE));
1497         if ((token.value.as_ulong % 4) != 0U)
1498                 isc_buffer_subtract(target,  4 - (token.value.as_ulong % 4));
1499
1500         /*
1501          * Checksum.
1502          */
1503         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1504                                       ISC_FALSE));
1505         oeor = strtol(DNS_AS_STR(token), &e, 16);
1506         if (*e != 0)
1507                 return (DNS_R_SYNTAX);
1508
1509         /*
1510          * Checksum.
1511          */
1512         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1513                                       ISC_FALSE));
1514         osum = strtol(DNS_AS_STR(token), &e, 16);
1515         if (*e != 0)
1516                 return (DNS_R_SYNTAX);
1517
1518         /*
1519          * Checksum.
1520          */
1521         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
1522                                       ISC_FALSE));
1523         orot = strtol(DNS_AS_STR(token), &e, 16);
1524         if (*e != 0)
1525                 return (DNS_R_SYNTAX);
1526
1527         if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
1528                 return(DNS_R_BADCKSUM);
1529         return (ISC_R_SUCCESS);
1530 }
1531
1532 /*
1533  * Encode binary byte c into ASCII representation and place into *bufp,
1534  * advancing bufp.
1535  */
1536 static isc_result_t
1537 byte_btoa(int c, isc_buffer_t *target, struct state *state) {
1538         isc_region_t tr;
1539
1540         isc_buffer_availableregion(target, &tr);
1541         Ceor ^= c;
1542         Csum += c;
1543         Csum += 1;
1544         if ((Crot & 0x80000000)) {
1545                 Crot <<= 1;
1546                 Crot += 1;
1547         } else {
1548                 Crot <<= 1;
1549         }
1550         Crot += c;
1551
1552         word <<= 8;
1553         word |= c;
1554         if (bcount == 3) {
1555                 if (word == 0) {
1556                         if (tr.length < 1)
1557                                 return (ISC_R_NOSPACE);
1558                         tr.base[0] = 'z';
1559                         isc_buffer_add(target, 1);
1560                 } else {
1561                     register int tmp = 0;
1562                     register isc_int32_t tmpword = word;
1563
1564                     if (tmpword < 0) {
1565                            /*
1566                             * Because some don't support u_long.
1567                             */
1568                         tmp = 32;
1569                         tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
1570                     }
1571                     if (tmpword < 0) {
1572                         tmp = 64;
1573                         tmpword -= (isc_int32_t)(85 * 85 * 85 * 85 * 32);
1574                     }
1575                         if (tr.length < 5)
1576                                 return (ISC_R_NOSPACE);
1577                         tr.base[0] = atob_digits[(tmpword /
1578                                               (isc_int32_t)(85 * 85 * 85 * 85))
1579                                                 + tmp];
1580                         tmpword %= (isc_int32_t)(85 * 85 * 85 * 85);
1581                         tr.base[1] = atob_digits[tmpword / (85 * 85 * 85)];
1582                         tmpword %= (85 * 85 * 85);
1583                         tr.base[2] = atob_digits[tmpword / (85 * 85)];
1584                         tmpword %= (85 * 85);
1585                         tr.base[3] = atob_digits[tmpword / 85];
1586                         tmpword %= 85;
1587                         tr.base[4] = atob_digits[tmpword];
1588                         isc_buffer_add(target, 5);
1589                 }
1590                 bcount = 0;
1591         } else {
1592                 bcount += 1;
1593         }
1594         return (ISC_R_SUCCESS);
1595 }
1596
1597
1598 /*
1599  * Encode the binary data from inbuf, of length inbuflen, into a
1600  * target.  Return success/failure status
1601  */
1602 static isc_result_t
1603 btoa_totext(unsigned char *inbuf, int inbuflen, isc_buffer_t *target) {
1604         int inc;
1605         struct state statebuf, *state = &statebuf;
1606         char buf[sizeof("x 2000000000 ffffffff ffffffff ffffffff")];
1607
1608         Ceor = Csum = Crot = word = bcount = 0;
1609         for (inc = 0; inc < inbuflen; inbuf++, inc++)
1610                 RETERR(byte_btoa(*inbuf, target, state));
1611
1612         while (bcount != 0)
1613                 RETERR(byte_btoa(0, target, state));
1614
1615         /*
1616          * Put byte count and checksum information at end of buffer,
1617          * delimited by 'x'
1618          */
1619         snprintf(buf, sizeof(buf), "x %d %x %x %x", inbuflen, Ceor, Csum, Crot);
1620         return (str_totext(buf, target));
1621 }
1622
1623
1624 static void
1625 default_fromtext_callback(dns_rdatacallbacks_t *callbacks, const char *fmt,
1626                           ...)
1627 {
1628         va_list ap;
1629
1630         UNUSED(callbacks);
1631
1632         va_start(ap, fmt);
1633         vfprintf(stderr, fmt, ap);
1634         va_end(ap);
1635         fprintf(stderr, "\n");
1636 }
1637
1638 static void
1639 fromtext_warneof(isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) {
1640         if (isc_lex_isfile(lexer) && callbacks != NULL) {
1641                 const char *name = isc_lex_getsourcename(lexer);
1642                 if (name == NULL)
1643                         name = "UNKNOWN";
1644                 (*callbacks->warn)(callbacks,
1645                                    "%s:%lu: file does not end with newline",
1646                                    name, isc_lex_getsourceline(lexer));
1647         }
1648 }
1649
1650 static void
1651 warn_badmx(isc_token_t *token, isc_lex_t *lexer,
1652            dns_rdatacallbacks_t *callbacks)
1653 {
1654         const char *file;
1655         unsigned long line;
1656
1657         if (lexer != NULL) {
1658                 file = isc_lex_getsourcename(lexer);
1659                 line = isc_lex_getsourceline(lexer);
1660                 (*callbacks->warn)(callbacks, "%s:%u: warning: '%s': %s",
1661                                    file, line, DNS_AS_STR(*token),
1662                                    dns_result_totext(DNS_R_MXISADDRESS));
1663         }
1664 }
1665
1666 static void
1667 warn_badname(dns_name_t *name, isc_lex_t *lexer,
1668              dns_rdatacallbacks_t *callbacks)
1669 {
1670         const char *file;
1671         unsigned long line;
1672         char namebuf[DNS_NAME_FORMATSIZE];
1673
1674         if (lexer != NULL) {
1675                 file = isc_lex_getsourcename(lexer);
1676                 line = isc_lex_getsourceline(lexer);
1677                 dns_name_format(name, namebuf, sizeof(namebuf));
1678                 (*callbacks->warn)(callbacks, "%s:%u: warning: %s: %s",
1679                                    file, line, namebuf,
1680                                    dns_result_totext(DNS_R_BADNAME));
1681         }
1682 }
1683
1684 static void
1685 fromtext_error(void (*callback)(dns_rdatacallbacks_t *, const char *, ...),
1686                dns_rdatacallbacks_t *callbacks, const char *name,
1687                unsigned long line, isc_token_t *token, isc_result_t result)
1688 {
1689         if (name == NULL)
1690                 name = "UNKNOWN";
1691
1692         if (token != NULL) {
1693                 switch (token->type) {
1694                 case isc_tokentype_eol:
1695                         (*callback)(callbacks, "%s: %s:%lu: near eol: %s",
1696                                     "dns_rdata_fromtext", name, line,
1697                                     dns_result_totext(result));
1698                         break;
1699                 case isc_tokentype_eof:
1700                         (*callback)(callbacks, "%s: %s:%lu: near eof: %s",
1701                                     "dns_rdata_fromtext", name, line,
1702                                     dns_result_totext(result));
1703                         break;
1704                 case isc_tokentype_number:
1705                         (*callback)(callbacks, "%s: %s:%lu: near %lu: %s",
1706                                     "dns_rdata_fromtext", name, line,
1707                                     token->value.as_ulong,
1708                                     dns_result_totext(result));
1709                         break;
1710                 case isc_tokentype_string:
1711                 case isc_tokentype_qstring:
1712                         (*callback)(callbacks, "%s: %s:%lu: near '%s': %s",
1713                                     "dns_rdata_fromtext", name, line,
1714                                     DNS_AS_STR(*token),
1715                                     dns_result_totext(result));
1716                         break;
1717                 default:
1718                         (*callback)(callbacks, "%s: %s:%lu: %s",
1719                                     "dns_rdata_fromtext", name, line,
1720                                     dns_result_totext(result));
1721                         break;
1722                 }
1723         } else {
1724                 (*callback)(callbacks, "dns_rdata_fromtext: %s:%lu: %s",
1725                             name, line, dns_result_totext(result));
1726         }
1727 }
1728
1729 dns_rdatatype_t
1730 dns_rdata_covers(dns_rdata_t *rdata) {
1731         if (rdata->type == 46)
1732                 return (covers_rrsig(rdata));
1733         return (covers_sig(rdata));
1734 }
1735
1736 isc_boolean_t
1737 dns_rdatatype_ismeta(dns_rdatatype_t type) {
1738         if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_META) != 0)
1739                 return (ISC_TRUE);
1740         return (ISC_FALSE);
1741 }
1742
1743 isc_boolean_t
1744 dns_rdatatype_issingleton(dns_rdatatype_t type) {
1745         if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_SINGLETON)
1746             != 0)
1747                 return (ISC_TRUE);
1748         return (ISC_FALSE);
1749 }
1750
1751 isc_boolean_t
1752 dns_rdatatype_notquestion(dns_rdatatype_t type) {
1753         if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_NOTQUESTION)
1754             != 0)
1755                 return (ISC_TRUE);
1756         return (ISC_FALSE);
1757 }
1758
1759 isc_boolean_t
1760 dns_rdatatype_questiononly(dns_rdatatype_t type) {
1761         if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_QUESTIONONLY)
1762             != 0)
1763                 return (ISC_TRUE);
1764         return (ISC_FALSE);
1765 }
1766
1767 isc_boolean_t
1768 dns_rdatatype_atparent(dns_rdatatype_t type) {
1769         if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_ATPARENT) != 0)
1770                 return (ISC_TRUE);
1771         return (ISC_FALSE);
1772 }
1773
1774 isc_boolean_t
1775 dns_rdataclass_ismeta(dns_rdataclass_t rdclass) {
1776
1777         if (rdclass == dns_rdataclass_reserved0
1778             || rdclass == dns_rdataclass_none
1779             || rdclass == dns_rdataclass_any)
1780                 return (ISC_TRUE);
1781
1782         return (ISC_FALSE);  /* Assume it is not a meta class. */
1783 }
1784
1785 isc_boolean_t
1786 dns_rdatatype_isdnssec(dns_rdatatype_t type) {
1787         if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_DNSSEC) != 0)
1788                 return (ISC_TRUE);
1789         return (ISC_FALSE);
1790 }
1791
1792 isc_boolean_t
1793 dns_rdatatype_iszonecutauth(dns_rdatatype_t type) {
1794         if ((dns_rdatatype_attributes(type)
1795              & (DNS_RDATATYPEATTR_DNSSEC | DNS_RDATATYPEATTR_ZONECUTAUTH))
1796             != 0)
1797                 return (ISC_TRUE);
1798         return (ISC_FALSE);
1799 }
1800
1801 isc_boolean_t
1802 dns_rdatatype_isknown(dns_rdatatype_t type) {
1803         if ((dns_rdatatype_attributes(type) & DNS_RDATATYPEATTR_UNKNOWN)
1804             == 0)
1805                 return (ISC_TRUE);
1806         return (ISC_FALSE);
1807 }
1808
1809 void
1810 dns_rdata_exists(dns_rdata_t *rdata, dns_rdatatype_t type) {
1811
1812         REQUIRE(rdata != NULL);
1813         REQUIRE(DNS_RDATA_INITIALIZED(rdata));
1814
1815         rdata->data = NULL;
1816         rdata->length = 0;
1817         rdata->flags = DNS_RDATA_UPDATE;
1818         rdata->type = type;
1819         rdata->rdclass = dns_rdataclass_any;
1820 }
1821
1822 void
1823 dns_rdata_notexist(dns_rdata_t *rdata, dns_rdatatype_t type) {
1824
1825         REQUIRE(rdata != NULL);
1826         REQUIRE(DNS_RDATA_INITIALIZED(rdata));
1827
1828         rdata->data = NULL;
1829         rdata->length = 0;
1830         rdata->flags = DNS_RDATA_UPDATE;
1831         rdata->type = type;
1832         rdata->rdclass = dns_rdataclass_none;
1833 }
1834
1835 void
1836 dns_rdata_deleterrset(dns_rdata_t *rdata, dns_rdatatype_t type) {
1837
1838         REQUIRE(rdata != NULL);
1839         REQUIRE(DNS_RDATA_INITIALIZED(rdata));
1840
1841         rdata->data = NULL;
1842         rdata->length = 0;
1843         rdata->flags = DNS_RDATA_UPDATE;
1844         rdata->type = type;
1845         rdata->rdclass = dns_rdataclass_any;
1846 }
1847
1848 void
1849 dns_rdata_makedelete(dns_rdata_t *rdata) {
1850         REQUIRE(rdata != NULL);
1851
1852         rdata->rdclass = dns_rdataclass_none;
1853 }
1854
1855 const char *
1856 dns_rdata_updateop(dns_rdata_t *rdata, dns_section_t section) {
1857
1858         REQUIRE(rdata != NULL);
1859         REQUIRE(DNS_RDATA_INITIALIZED(rdata));
1860
1861         switch (section) {
1862         case DNS_SECTION_PREREQUISITE:
1863                 switch (rdata->rdclass) {
1864                 case dns_rdataclass_none:
1865                         switch (rdata->type) {
1866                         case dns_rdatatype_any:
1867                                 return ("domain doesn't exist");
1868                         default:
1869                                 return ("rrset doesn't exist");
1870                         }
1871                 case dns_rdataclass_any:
1872                         switch (rdata->type) {
1873                         case dns_rdatatype_any:
1874                                 return ("domain exists");
1875                         default:
1876                                 return ("rrset exists (value independent)");
1877                         }
1878                 default:
1879                         return ("rrset exists (value dependent)");
1880                 }
1881         case DNS_SECTION_UPDATE:
1882                 switch (rdata->rdclass) {
1883                 case dns_rdataclass_none:
1884                         return ("delete");
1885                 case dns_rdataclass_any:
1886                         switch (rdata->type) {
1887                         case dns_rdatatype_any:
1888                                 return ("delete all rrsets");
1889                         default:
1890                                 return ("delete rrset");
1891                         }
1892                 default:
1893                         return ("add");
1894                 }
1895         }
1896         return ("invalid");
1897 }