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