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