Bug Summary

File:src/usr.bin/dig/lib/dns/name.c
Warning:line 1250, column 10
Access to field 'base' results in a dereference of a null pointer (loaded from variable 'target')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name name.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/dig/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.bin/dig -I /usr/src/usr.bin/dig/obj -I /usr/src/usr.bin/dig/bin/dig/include -I /usr/src/usr.bin/dig/lib/dns/include -I /usr/src/usr.bin/dig/lib/isc/include -I /usr/src/usr.bin/dig/lib/isccfg/include -I /usr/src/usr.bin/dig/lib/lwres/include -D VERSION="9.10.8-P1" -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/dig/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/dig/lib/dns/name.c
1/*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
17/* $Id: name.c,v 1.14 2020/09/14 08:40:43 florian Exp $ */
18
19/*! \file */
20#include <ctype.h>
21#include <stdlib.h>
22#include <isc/buffer.h>
23#include <isc/hash.h>
24
25#include <string.h>
26#include <isc/util.h>
27
28#include <dns/compress.h>
29#include <dns/fixedname.h>
30#include <dns/name.h>
31#include <dns/result.h>
32
33typedef enum {
34 ft_init = 0,
35 ft_start,
36 ft_ordinary,
37 ft_initialescape,
38 ft_escape,
39 ft_escdecimal,
40 ft_at
41} ft_state;
42
43typedef enum {
44 fw_start = 0,
45 fw_ordinary,
46 fw_newcurrent
47} fw_state;
48
49static char digitvalue[256] = {
50 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
51 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
52 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
53 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
54 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
55 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
56 -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
57 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
58 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
59 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
60 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
61 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
62 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
63 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
64 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
65 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
66};
67
68static unsigned char maptolower[] = {
69 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
70 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
71 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
72 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
73 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
74 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
75 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
76 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
77 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
78 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
79 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
80 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
81 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
82 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
83 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
84 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
85 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
86 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
87 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
88 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
89 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
90 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
91 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
92 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
93 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
94 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
95 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
96 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
97 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
98 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
99 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
100 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
101};
102
103#define CONVERTTOASCII(c)
104#define CONVERTFROMASCII(c)
105
106#define INIT_OFFSETS(name, var, default_offsets)if ((name)->offsets != ((void *)0)) var = (name)->offsets
; else var = (default_offsets);
\
107 if ((name)->offsets != NULL((void *)0)) \
108 var = (name)->offsets; \
109 else \
110 var = (default_offsets);
111
112#define SETUP_OFFSETS(name, var, default_offsets)if ((name)->offsets != ((void *)0)) var = (name)->offsets
; else { var = (default_offsets); set_offsets(name, var, ((void
*)0)); }
\
113 if ((name)->offsets != NULL((void *)0)) \
114 var = (name)->offsets; \
115 else { \
116 var = (default_offsets); \
117 set_offsets(name, var, NULL((void *)0)); \
118 }
119
120/*%
121 * Note: If additional attributes are added that should not be set for
122 * empty names, MAKE_EMPTY() must be changed so it clears them.
123 */
124#define MAKE_EMPTY(name)do { name->ndata = ((void *)0); name->length = 0; name->
labels = 0; name->attributes &= ~0x00000001; } while (
0);
\
125do { \
126 name->ndata = NULL((void *)0); \
127 name->length = 0; \
128 name->labels = 0; \
129 name->attributes &= ~DNS_NAMEATTR_ABSOLUTE0x00000001; \
130} while (0);
131
132/*%
133 * A name is "bindable" if it can be set to point to a new value, i.e.
134 * name->ndata and name->length may be changed.
135 */
136#define BINDABLE(name)((name->attributes & (0x00000002|0x00000004)) == 0) \
137 ((name->attributes & (DNS_NAMEATTR_READONLY0x00000002|DNS_NAMEATTR_DYNAMIC0x00000004)) \
138 == 0)
139
140/*%
141 * Note that the name data must be a char array, not a string
142 * literal, to avoid compiler warnings about discarding
143 * the const attribute of a string.
144 */
145static unsigned char root_ndata[] = { "" };
146static unsigned char root_offsets[] = { 0 };
147
148static dns_name_t root = DNS_NAME_INITABSOLUTE(root_ndata, root_offsets){ root_ndata, sizeof(root_ndata), sizeof(root_offsets), 0x00000002
| 0x00000001, root_offsets, ((void *)0), { (void *)-1, (void
*)-1}, {((void *)0), ((void *)0)} }
;
149
150/* XXXDCL make const? */
151dns_name_t *dns_rootname = &root;
152
153static void
154set_offsets(const dns_name_t *name, unsigned char *offsets,
155 dns_name_t *set_name);
156
157void
158dns_name_init(dns_name_t *name, unsigned char *offsets) {
159 /*
160 * Initialize 'name'.
161 */
162 name->ndata = NULL((void *)0);
163 name->length = 0;
164 name->labels = 0;
165 name->attributes = 0;
166 name->offsets = offsets;
167 name->buffer = NULL((void *)0);
168 ISC_LINK_INIT(name, link)do { (name)->link.prev = (void *)(-1); (name)->link.next
= (void *)(-1); } while (0)
;
169 ISC_LIST_INIT(name->list)do { (name->list).head = ((void *)0); (name->list).tail
= ((void *)0); } while (0)
;
170
171}
172
173void
174dns_name_reset(dns_name_t *name) {
175 REQUIRE(BINDABLE(name))((void) ((((name->attributes & (0x00000002|0x00000004)
) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 175, isc_assertiontype_require, "((name->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
176
177 name->ndata = NULL((void *)0);
178 name->length = 0;
179 name->labels = 0;
180 name->attributes &= ~DNS_NAMEATTR_ABSOLUTE0x00000001;
181 if (name->buffer != NULL((void *)0))
182 isc_buffer_clearisc__buffer_clear(name->buffer);
183}
184
185void
186dns_name_invalidate(dns_name_t *name) {
187 /*
188 * Make 'name' invalid.
189 */
190
191 name->ndata = NULL((void *)0);
192 name->length = 0;
193 name->labels = 0;
194 name->attributes = 0;
195 name->offsets = NULL((void *)0);
196 name->buffer = NULL((void *)0);
197 ISC_LINK_INIT(name, link)do { (name)->link.prev = (void *)(-1); (name)->link.next
= (void *)(-1); } while (0)
;
198}
199
200void
201dns_name_setbuffer(dns_name_t *name, isc_buffer_t *buffer) {
202 /*
203 * Dedicate a buffer for use with 'name'.
204 */
205
206 REQUIRE((buffer != NULL && name->buffer == NULL) ||((void) (((buffer != ((void *)0) && name->buffer ==
((void *)0)) || (buffer == ((void *)0))) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 207, isc_assertiontype_require
, "(buffer != ((void *)0) && name->buffer == ((void *)0)) || (buffer == ((void *)0))"
), 0)))
207 (buffer == NULL))((void) (((buffer != ((void *)0) && name->buffer ==
((void *)0)) || (buffer == ((void *)0))) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 207, isc_assertiontype_require
, "(buffer != ((void *)0) && name->buffer == ((void *)0)) || (buffer == ((void *)0))"
), 0)))
;
208
209 name->buffer = buffer;
210}
211
212int
213dns_name_isabsolute(const dns_name_t *name) {
214
215 /*
216 * Does 'name' end in the root label?
217 */
218
219 if ((name->attributes & DNS_NAMEATTR_ABSOLUTE0x00000001) != 0)
220 return (1);
221 return (0);
222}
223
224unsigned int
225dns_name_hash(dns_name_t *name, int case_sensitive) {
226 unsigned int length;
227
228 /*
229 * Provide a hash value for 'name'.
230 */
231
232 if (name->labels == 0)
233 return (0);
234
235 length = name->length;
236 if (length > 16)
237 length = 16;
238
239 return (isc_hash_function_reverse(name->ndata, length,
240 case_sensitive, NULL((void *)0)));
241}
242
243dns_namereln_t
244dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
245 int *orderp, unsigned int *nlabelsp)
246{
247 unsigned int l1, l2, l, count1, count2, count, nlabels;
248 int cdiff, ldiff, chdiff;
249 unsigned char *label1, *label2;
250 unsigned char *offsets1, *offsets2;
251 dns_offsets_t odata1, odata2;
252 dns_namereln_t namereln = dns_namereln_none;
253
254 /*
255 * Determine the relative ordering under the DNSSEC order relation of
256 * 'name1' and 'name2', and also determine the hierarchical
257 * relationship of the names.
258 *
259 * Note: It makes no sense for one of the names to be relative and the
260 * other absolute. If both names are relative, then to be meaningfully
261 * compared the caller must ensure that they are both relative to the
262 * same domain.
263 */
264
265 REQUIRE(orderp != NULL)((void) ((orderp != ((void *)0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 265, isc_assertiontype_require, "orderp != ((void *)0)"), 0
)))
;
266 REQUIRE(nlabelsp != NULL)((void) ((nlabelsp != ((void *)0)) || ((isc_assertion_failed)
("/usr/src/usr.bin/dig/lib/dns/name.c", 266, isc_assertiontype_require
, "nlabelsp != ((void *)0)"), 0)))
;
267 /*
268 * Either name1 is absolute and name2 is absolute, or neither is.
269 */
270 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==((void) (((name1->attributes & 0x00000001) == (name2->
attributes & 0x00000001)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 271, isc_assertiontype_require, "(name1->attributes & 0x00000001) == (name2->attributes & 0x00000001)"
), 0)))
271 (name2->attributes & DNS_NAMEATTR_ABSOLUTE))((void) (((name1->attributes & 0x00000001) == (name2->
attributes & 0x00000001)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 271, isc_assertiontype_require, "(name1->attributes & 0x00000001) == (name2->attributes & 0x00000001)"
), 0)))
;
272
273 if (name1 == name2) {
274 *orderp = 0;
275 *nlabelsp = name1->labels;
276 return (dns_namereln_equal);
277 }
278
279 SETUP_OFFSETS(name1, offsets1, odata1)if ((name1)->offsets != ((void *)0)) offsets1 = (name1)->
offsets; else { offsets1 = (odata1); set_offsets(name1, offsets1
, ((void *)0)); }
;
280 SETUP_OFFSETS(name2, offsets2, odata2)if ((name2)->offsets != ((void *)0)) offsets2 = (name2)->
offsets; else { offsets2 = (odata2); set_offsets(name2, offsets2
, ((void *)0)); }
;
281
282 nlabels = 0;
283 l1 = name1->labels;
284 l2 = name2->labels;
285 if (l2 > l1) {
286 l = l1;
287 ldiff = 0 - (l2 - l1);
288 } else {
289 l = l2;
290 ldiff = l1 - l2;
291 }
292
293 offsets1 += l1;
294 offsets2 += l2;
295
296 while (l > 0) {
297 l--;
298 offsets1--;
299 offsets2--;
300 label1 = &name1->ndata[*offsets1];
301 label2 = &name2->ndata[*offsets2];
302 count1 = *label1++;
303 count2 = *label2++;
304
305 /*
306 * We dropped bitstring labels, and we don't support any
307 * other extended label types.
308 */
309 INSIST(count1 <= 63 && count2 <= 63)((void) ((count1 <= 63 && count2 <= 63) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 309, isc_assertiontype_insist
, "count1 <= 63 && count2 <= 63"), 0)))
;
310
311 cdiff = (int)count1 - (int)count2;
312 if (cdiff < 0)
313 count = count1;
314 else
315 count = count2;
316
317 /* Loop unrolled for performance */
318 while (count > 3) {
319 chdiff = (int)maptolower[label1[0]] -
320 (int)maptolower[label2[0]];
321 if (chdiff != 0) {
322 *orderp = chdiff;
323 goto done;
324 }
325 chdiff = (int)maptolower[label1[1]] -
326 (int)maptolower[label2[1]];
327 if (chdiff != 0) {
328 *orderp = chdiff;
329 goto done;
330 }
331 chdiff = (int)maptolower[label1[2]] -
332 (int)maptolower[label2[2]];
333 if (chdiff != 0) {
334 *orderp = chdiff;
335 goto done;
336 }
337 chdiff = (int)maptolower[label1[3]] -
338 (int)maptolower[label2[3]];
339 if (chdiff != 0) {
340 *orderp = chdiff;
341 goto done;
342 }
343 count -= 4;
344 label1 += 4;
345 label2 += 4;
346 }
347 while (count-- > 0) {
348 chdiff = (int)maptolower[*label1++] -
349 (int)maptolower[*label2++];
350 if (chdiff != 0) {
351 *orderp = chdiff;
352 goto done;
353 }
354 }
355 if (cdiff != 0) {
356 *orderp = cdiff;
357 goto done;
358 }
359 nlabels++;
360 }
361
362 *orderp = ldiff;
363 if (ldiff < 0)
364 namereln = dns_namereln_contains;
365 else if (ldiff > 0)
366 namereln = dns_namereln_subdomain;
367 else
368 namereln = dns_namereln_equal;
369 *nlabelsp = nlabels;
370 return (namereln);
371
372 done:
373 *nlabelsp = nlabels;
374 if (nlabels > 0)
375 namereln = dns_namereln_commonancestor;
376
377 return (namereln);
378}
379
380int
381dns_name_compare(const dns_name_t *name1, const dns_name_t *name2) {
382 int order;
383 unsigned int nlabels;
384
385 /*
386 * Determine the relative ordering under the DNSSEC order relation of
387 * 'name1' and 'name2'.
388 *
389 * Note: It makes no sense for one of the names to be relative and the
390 * other absolute. If both names are relative, then to be meaningfully
391 * compared the caller must ensure that they are both relative to the
392 * same domain.
393 */
394
395 (void)dns_name_fullcompare(name1, name2, &order, &nlabels);
396
397 return (order);
398}
399
400int
401dns_name_equal(const dns_name_t *name1, const dns_name_t *name2) {
402 unsigned int l, count;
403 unsigned char c;
404 unsigned char *label1, *label2;
405
406 /*
407 * Are 'name1' and 'name2' equal?
408 *
409 * Note: It makes no sense for one of the names to be relative and the
410 * other absolute. If both names are relative, then to be meaningfully
411 * compared the caller must ensure that they are both relative to the
412 * same domain.
413 */
414
415 /*
416 * Either name1 is absolute and name2 is absolute, or neither is.
417 */
418 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==((void) (((name1->attributes & 0x00000001) == (name2->
attributes & 0x00000001)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 419, isc_assertiontype_require, "(name1->attributes & 0x00000001) == (name2->attributes & 0x00000001)"
), 0)))
419 (name2->attributes & DNS_NAMEATTR_ABSOLUTE))((void) (((name1->attributes & 0x00000001) == (name2->
attributes & 0x00000001)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 419, isc_assertiontype_require, "(name1->attributes & 0x00000001) == (name2->attributes & 0x00000001)"
), 0)))
;
420
421 if (name1 == name2)
422 return (1);
423
424 if (name1->length != name2->length)
425 return (0);
426
427 l = name1->labels;
428
429 if (l != name2->labels)
430 return (0);
431
432 label1 = name1->ndata;
433 label2 = name2->ndata;
434 while (l-- > 0) {
435 count = *label1++;
436 if (count != *label2++)
437 return (0);
438
439 INSIST(count <= 63)((void) ((count <= 63) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 439, isc_assertiontype_insist, "count <= 63"), 0)))
; /* no bitstring support */
440
441 /* Loop unrolled for performance */
442 while (count > 3) {
443 c = maptolower[label1[0]];
444 if (c != maptolower[label2[0]])
445 return (0);
446 c = maptolower[label1[1]];
447 if (c != maptolower[label2[1]])
448 return (0);
449 c = maptolower[label1[2]];
450 if (c != maptolower[label2[2]])
451 return (0);
452 c = maptolower[label1[3]];
453 if (c != maptolower[label2[3]])
454 return (0);
455 count -= 4;
456 label1 += 4;
457 label2 += 4;
458 }
459 while (count-- > 0) {
460 c = maptolower[*label1++];
461 if (c != maptolower[*label2++])
462 return (0);
463 }
464 }
465
466 return (1);
467}
468
469int
470dns_name_caseequal(const dns_name_t *name1, const dns_name_t *name2) {
471
472 /*
473 * Are 'name1' and 'name2' equal?
474 *
475 * Note: It makes no sense for one of the names to be relative and the
476 * other absolute. If both names are relative, then to be meaningfully
477 * compared the caller must ensure that they are both relative to the
478 * same domain.
479 */
480
481 /*
482 * Either name1 is absolute and name2 is absolute, or neither is.
483 */
484 REQUIRE((name1->attributes & DNS_NAMEATTR_ABSOLUTE) ==((void) (((name1->attributes & 0x00000001) == (name2->
attributes & 0x00000001)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 485, isc_assertiontype_require, "(name1->attributes & 0x00000001) == (name2->attributes & 0x00000001)"
), 0)))
485 (name2->attributes & DNS_NAMEATTR_ABSOLUTE))((void) (((name1->attributes & 0x00000001) == (name2->
attributes & 0x00000001)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 485, isc_assertiontype_require, "(name1->attributes & 0x00000001) == (name2->attributes & 0x00000001)"
), 0)))
;
486
487 if (name1->length != name2->length)
488 return (0);
489
490 if (memcmp(name1->ndata, name2->ndata, name1->length) != 0)
491 return (0);
492
493 return (1);
494}
495
496int
497dns_name_issubdomain(const dns_name_t *name1, const dns_name_t *name2) {
498 int order;
499 unsigned int nlabels;
500 dns_namereln_t namereln;
501
502 /*
503 * Is 'name1' a subdomain of 'name2'?
504 *
505 * Note: It makes no sense for one of the names to be relative and the
506 * other absolute. If both names are relative, then to be meaningfully
507 * compared the caller must ensure that they are both relative to the
508 * same domain.
509 */
510
511 namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
512 if (namereln == dns_namereln_subdomain ||
513 namereln == dns_namereln_equal)
514 return (1);
515
516 return (0);
517}
518
519unsigned int
520dns_name_countlabels(const dns_name_t *name) {
521 /*
522 * How many labels does 'name' have?
523 */
524
525 ENSURE(name->labels <= 128)((void) ((name->labels <= 128) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 525, isc_assertiontype_ensure
, "name->labels <= 128"), 0)))
;
526
527 return (name->labels);
528}
529
530void
531dns_name_getlabel(const dns_name_t *name, unsigned int n, dns_label_t *label) {
532 unsigned char *offsets;
533 dns_offsets_t odata;
534
535 /*
536 * Make 'label' refer to the 'n'th least significant label of 'name'.
537 */
538
539 REQUIRE(name->labels > 0)((void) ((name->labels > 0) || ((isc_assertion_failed)(
"/usr/src/usr.bin/dig/lib/dns/name.c", 539, isc_assertiontype_require
, "name->labels > 0"), 0)))
;
540 REQUIRE(n < name->labels)((void) ((n < name->labels) || ((isc_assertion_failed)(
"/usr/src/usr.bin/dig/lib/dns/name.c", 540, isc_assertiontype_require
, "n < name->labels"), 0)))
;
541 REQUIRE(label != NULL)((void) ((label != ((void *)0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 541, isc_assertiontype_require, "label != ((void *)0)"), 0)
))
;
542
543 SETUP_OFFSETS(name, offsets, odata)if ((name)->offsets != ((void *)0)) offsets = (name)->offsets
; else { offsets = (odata); set_offsets(name, offsets, ((void
*)0)); }
;
544
545 label->base = &name->ndata[offsets[n]];
546 if (n == name->labels - 1)
547 label->length = name->length - offsets[n];
548 else
549 label->length = offsets[n + 1] - offsets[n];
550}
551
552void
553dns_name_getlabelsequence(const dns_name_t *source,
554 unsigned int first, unsigned int n,
555 dns_name_t *target)
556{
557 unsigned char *offsets;
558 dns_offsets_t odata;
559 unsigned int firstoffset, endoffset;
560
561 /*
562 * Make 'target' refer to the 'n' labels including and following
563 * 'first' in 'source'.
564 */
565
566 REQUIRE(first <= source->labels)((void) ((first <= source->labels) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 566, isc_assertiontype_require
, "first <= source->labels"), 0)))
;
567 REQUIRE(n <= source->labels - first)((void) ((n <= source->labels - first) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 567, isc_assertiontype_require
, "n <= source->labels - first"), 0)))
; /* note first+n could overflow */
568 REQUIRE(BINDABLE(target))((void) ((((target->attributes & (0x00000002|0x00000004
)) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 568, isc_assertiontype_require, "((target->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
569
570 SETUP_OFFSETS(source, offsets, odata)if ((source)->offsets != ((void *)0)) offsets = (source)->
offsets; else { offsets = (odata); set_offsets(source, offsets
, ((void *)0)); }
;
571
572 if (first == source->labels)
573 firstoffset = source->length;
574 else
575 firstoffset = offsets[first];
576
577 if (first + n == source->labels)
578 endoffset = source->length;
579 else
580 endoffset = offsets[first + n];
581
582 target->ndata = &source->ndata[firstoffset];
583 target->length = endoffset - firstoffset;
584
585 if (first + n == source->labels && n > 0 &&
586 (source->attributes & DNS_NAMEATTR_ABSOLUTE0x00000001) != 0)
587 target->attributes |= DNS_NAMEATTR_ABSOLUTE0x00000001;
588 else
589 target->attributes &= ~DNS_NAMEATTR_ABSOLUTE0x00000001;
590
591 target->labels = n;
592
593 /*
594 * If source and target are the same, and we're making target
595 * a prefix of source, the offsets table is correct already
596 * so we don't need to call set_offsets().
597 */
598 if (target->offsets != NULL((void *)0) &&
599 (target != source || first != 0))
600 set_offsets(target, target->offsets, NULL((void *)0));
601}
602
603void
604dns_name_clone(const dns_name_t *source, dns_name_t *target) {
605
606 /*
607 * Make 'target' refer to the same name as 'source'.
608 */
609
610 REQUIRE(BINDABLE(target))((void) ((((target->attributes & (0x00000002|0x00000004
)) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 610, isc_assertiontype_require, "((target->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
611
612 target->ndata = source->ndata;
613 target->length = source->length;
614 target->labels = source->labels;
615 target->attributes = source->attributes &
616 (unsigned int)~(DNS_NAMEATTR_READONLY0x00000002 | DNS_NAMEATTR_DYNAMIC0x00000004 |
617 DNS_NAMEATTR_DYNOFFSETS0x00000008);
618 if (target->offsets != NULL((void *)0) && source->labels > 0) {
619 if (source->offsets != NULL((void *)0))
620 memmove(target->offsets, source->offsets,
621 source->labels);
622 else
623 set_offsets(target, target->offsets, NULL((void *)0));
624 }
625}
626
627void
628dns_name_fromregion(dns_name_t *name, const isc_region_t *r) {
629 unsigned char *offsets;
630 dns_offsets_t odata;
631 unsigned int len;
632 isc_region_t r2;
633
634 /*
635 * Make 'name' refer to region 'r'.
636 */
637
638 REQUIRE(r != NULL)((void) ((r != ((void *)0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 638, isc_assertiontype_require, "r != ((void *)0)"), 0)))
;
639 REQUIRE(BINDABLE(name))((void) ((((name->attributes & (0x00000002|0x00000004)
) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 639, isc_assertiontype_require, "((name->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
640
641 INIT_OFFSETS(name, offsets, odata)if ((name)->offsets != ((void *)0)) offsets = (name)->offsets
; else offsets = (odata);
;
642
643 if (name->buffer != NULL((void *)0)) {
644 isc_buffer_clearisc__buffer_clear(name->buffer);
645 isc_buffer_availableregionisc__buffer_availableregion(name->buffer, &r2);
646 len = (r->length < r2.length) ? r->length : r2.length;
647 if (len > DNS_NAME_MAXWIRE255)
648 len = DNS_NAME_MAXWIRE255;
649 if (len != 0)
650 memmove(r2.base, r->base, len);
651 name->ndata = r2.base;
652 name->length = len;
653 } else {
654 name->ndata = r->base;
655 name->length = (r->length <= DNS_NAME_MAXWIRE255) ?
656 r->length : DNS_NAME_MAXWIRE255;
657 }
658
659 if (r->length > 0)
660 set_offsets(name, offsets, name);
661 else {
662 name->labels = 0;
663 name->attributes &= ~DNS_NAMEATTR_ABSOLUTE0x00000001;
664 }
665
666 if (name->buffer != NULL((void *)0))
667 isc_buffer_addisc__buffer_add(name->buffer, name->length);
668}
669
670void
671dns_name_toregion(dns_name_t *name, isc_region_t *r) {
672 /*
673 * Make 'r' refer to 'name'.
674 */
675
676 REQUIRE(r != NULL)((void) ((r != ((void *)0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 676, isc_assertiontype_require, "r != ((void *)0)"), 0)))
;
677
678 r->base = name->ndata;
679 r->length = name->length;
680}
681
682isc_result_t
683dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
684 const dns_name_t *origin, unsigned int options,
685 isc_buffer_t *target)
686{
687 unsigned char *ndata, *label = NULL((void *)0);
688 char *tdata;
689 char c;
690 ft_state state;
691 unsigned int value = 0, count = 0;
692 unsigned int n1 = 0, n2 = 0;
693 unsigned int tlen, nrem, nused, digits = 0, labels, tused;
694 int done;
695 unsigned char *offsets;
696 dns_offsets_t odata;
697 int downcase;
698
699 /*
700 * Convert the textual representation of a DNS name at source
701 * into uncompressed wire form stored in target.
702 *
703 * Notes:
704 * Relative domain names will have 'origin' appended to them
705 * unless 'origin' is NULL, in which case relative domain names
706 * will remain relative.
707 */
708
709 downcase = (options & DNS_NAME_DOWNCASE0x0001) != 0;
710
711 if (target == NULL((void *)0) && name->buffer != NULL((void *)0)) {
712 target = name->buffer;
713 isc_buffer_clearisc__buffer_clear(target);
714 }
715
716 REQUIRE(BINDABLE(name))((void) ((((name->attributes & (0x00000002|0x00000004)
) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 716, isc_assertiontype_require, "((name->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
717
718 INIT_OFFSETS(name, offsets, odata)if ((name)->offsets != ((void *)0)) offsets = (name)->offsets
; else offsets = (odata);
;
719 offsets[0] = 0;
720
721 /*
722 * Make 'name' empty in case of failure.
723 */
724 MAKE_EMPTY(name)do { name->ndata = ((void *)0); name->length = 0; name->
labels = 0; name->attributes &= ~0x00000001; } while (
0);
;
725
726 /*
727 * Set up the state machine.
728 */
729 tdata = (char *)source->base + source->current;
730 tlen = isc_buffer_remaininglength(source)((source)->used - (source)->current);
731 tused = 0;
732 ndata = isc_buffer_used(target)((void *)((unsigned char *)(target)->base + (target)->used
))
;
733 nrem = isc_buffer_availablelength(target)((target)->length - (target)->used);
734 if (nrem > 255)
735 nrem = 255;
736 nused = 0;
737 labels = 0;
738 done = 0;
739 state = ft_init;
740
741 while (nrem > 0 && tlen > 0 && !done) {
742 c = *tdata++;
743 tlen--;
744 tused++;
745
746 switch (state) {
747 case ft_init:
748 /*
749 * Is this the root name?
750 */
751 if (c == '.') {
752 if (tlen != 0)
753 return (DNS_R_EMPTYLABEL(((1) << 16) + 4));
754 labels++;
755 *ndata++ = 0;
756 nrem--;
757 nused++;
758 done = 1;
759 break;
760 }
761 if (c == '@' && tlen == 0) {
762 state = ft_at;
763 break;
764 }
765
766 /* FALLTHROUGH */
767 case ft_start:
768 label = ndata;
769 ndata++;
770 nrem--;
771 nused++;
772 count = 0;
773 if (c == '\\') {
774 state = ft_initialescape;
775 break;
776 }
777 state = ft_ordinary;
778 if (nrem == 0)
779 return (ISC_R_NOSPACE19);
780 /* FALLTHROUGH */
781 case ft_ordinary:
782 if (c == '.') {
783 if (count == 0)
784 return (DNS_R_EMPTYLABEL(((1) << 16) + 4));
785 *label = count;
786 labels++;
787 INSIST(labels <= 127)((void) ((labels <= 127) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 787, isc_assertiontype_insist, "labels <= 127"), 0)))
;
788 offsets[labels] = nused;
789 if (tlen == 0) {
790 labels++;
791 *ndata++ = 0;
792 nrem--;
793 nused++;
794 done = 1;
795 }
796 state = ft_start;
797 } else if (c == '\\') {
798 state = ft_escape;
799 } else {
800 if (count >= 63)
801 return (DNS_R_LABELTOOLONG(((1) << 16) + 0));
802 count++;
803 CONVERTTOASCII(c);
804 if (downcase)
805 c = maptolower[c & 0xff];
806 *ndata++ = c;
807 nrem--;
808 nused++;
809 }
810 break;
811 case ft_initialescape:
812 if (c == '[') {
813 /*
814 * This looks like a bitstring label, which
815 * was deprecated. Intentionally drop it.
816 */
817 return (DNS_R_BADLABELTYPE(((1) << 16) + 8));
818 }
819 state = ft_escape;
820 POST(state)(void)(state);
821 /* FALLTHROUGH */
822 case ft_escape:
823 if (!isdigit(c & 0xff)) {
824 if (count >= 63)
825 return (DNS_R_LABELTOOLONG(((1) << 16) + 0));
826 count++;
827 CONVERTTOASCII(c);
828 if (downcase)
829 c = maptolower[c & 0xff];
830 *ndata++ = c;
831 nrem--;
832 nused++;
833 state = ft_ordinary;
834 break;
835 }
836 digits = 0;
837 value = 0;
838 state = ft_escdecimal;
839 /* FALLTHROUGH */
840 case ft_escdecimal:
841 if (!isdigit(c & 0xff))
842 return (DNS_R_BADESCAPE(((1) << 16) + 1));
843 value *= 10;
844 value += digitvalue[c & 0xff];
845 digits++;
846 if (digits == 3) {
847 if (value > 255)
848 return (DNS_R_BADESCAPE(((1) << 16) + 1));
849 if (count >= 63)
850 return (DNS_R_LABELTOOLONG(((1) << 16) + 0));
851 count++;
852 if (downcase)
853 value = maptolower[value];
854 *ndata++ = value;
855 nrem--;
856 nused++;
857 state = ft_ordinary;
858 }
859 break;
860 default:
861 FATAL_ERRORisc_error_fatal(__FILE__"/usr/src/usr.bin/dig/lib/dns/name.c", __LINE__861,
862 "Unexpected state %d", state);
863 /* Does not return. */
864 }
865 }
866
867 if (!done) {
868 if (nrem == 0)
869 return (ISC_R_NOSPACE19);
870 INSIST(tlen == 0)((void) ((tlen == 0) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 870, isc_assertiontype_insist, "tlen == 0"), 0)))
;
871 if (state != ft_ordinary && state != ft_at)
872 return (ISC_R_UNEXPECTEDEND24);
873 if (state == ft_ordinary) {
874 INSIST(count != 0)((void) ((count != 0) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 874, isc_assertiontype_insist, "count != 0"), 0)))
;
875 *label = count;
876 labels++;
877 INSIST(labels <= 127)((void) ((labels <= 127) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 877, isc_assertiontype_insist, "labels <= 127"), 0)))
;
878 offsets[labels] = nused;
879 }
880 if (origin != NULL((void *)0)) {
881 if (nrem < origin->length)
882 return (ISC_R_NOSPACE19);
883 label = origin->ndata;
884 n1 = origin->length;
885 nrem -= n1;
886 POST(nrem)(void)(nrem);
887 while (n1 > 0) {
888 n2 = *label++;
889 INSIST(n2 <= 63)((void) ((n2 <= 63) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 889, isc_assertiontype_insist, "n2 <= 63"), 0)))
; /* no bitstring support */
890 *ndata++ = n2;
891 n1 -= n2 + 1;
892 nused += n2 + 1;
893 while (n2 > 0) {
894 c = *label++;
895 if (downcase)
896 c = maptolower[c & 0xff];
897 *ndata++ = c;
898 n2--;
899 }
900 labels++;
901 if (n1 > 0) {
902 INSIST(labels <= 127)((void) ((labels <= 127) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 902, isc_assertiontype_insist, "labels <= 127"), 0)))
;
903 offsets[labels] = nused;
904 }
905 }
906 if ((origin->attributes & DNS_NAMEATTR_ABSOLUTE0x00000001) != 0)
907 name->attributes |= DNS_NAMEATTR_ABSOLUTE0x00000001;
908 }
909 } else
910 name->attributes |= DNS_NAMEATTR_ABSOLUTE0x00000001;
911
912 name->ndata = (unsigned char *)target->base + target->used;
913 name->labels = labels;
914 name->length = nused;
915
916 isc_buffer_forwardisc__buffer_forward(source, tused);
917 isc_buffer_addisc__buffer_add(target, name->length);
918
919 return (ISC_R_SUCCESS0);
920}
921
922isc_result_t
923dns_name_totext(dns_name_t *name, int omit_final_dot,
924 isc_buffer_t *target)
925{
926 unsigned int options = DNS_NAME_MASTERFILE0x02U;
927
928 if (omit_final_dot)
929 options |= DNS_NAME_OMITFINALDOT0x01U;
930 return (dns_name_totext2(name, options, target));
931}
932
933isc_result_t
934dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target)
935{
936 unsigned char *ndata;
937 char *tdata;
938 unsigned int nlen, tlen;
939 unsigned char c;
940 unsigned int trem, count;
941 unsigned int labels;
942 int saw_root = 0;
943 int omit_final_dot = options & DNS_NAME_OMITFINALDOT0x01U;
944
945 /*
946 * This function assumes the name is in proper uncompressed
947 * wire format.
948 */
949
950 ndata = name->ndata;
951 nlen = name->length;
952 labels = name->labels;
953 tdata = isc_buffer_used(target)((void *)((unsigned char *)(target)->base + (target)->used
))
;
954 tlen = isc_buffer_availablelength(target)((target)->length - (target)->used);
955
956 trem = tlen;
957
958 if (labels == 0 && nlen == 0) {
959 /*
960 * Special handling for an empty name.
961 */
962 if (trem == 0)
963 return (ISC_R_NOSPACE19);
964
965 /*
966 * The names of these booleans are misleading in this case.
967 * This empty name is not necessarily from the root node of
968 * the DNS root zone, nor is a final dot going to be included.
969 * They need to be set this way, though, to keep the "@"
970 * from being trounced.
971 */
972 saw_root = 1;
973 omit_final_dot = 0;
974 *tdata++ = '@';
975 trem--;
976
977 /*
978 * Skip the while() loop.
979 */
980 nlen = 0;
981 } else if (nlen == 1 && labels == 1 && *ndata == '\0') {
982 /*
983 * Special handling for the root label.
984 */
985 if (trem == 0)
986 return (ISC_R_NOSPACE19);
987
988 saw_root = 1;
989 omit_final_dot = 0;
990 *tdata++ = '.';
991 trem--;
992
993 /*
994 * Skip the while() loop.
995 */
996 nlen = 0;
997 }
998
999 while (labels > 0 && nlen > 0 && trem > 0) {
1000 labels--;
1001 count = *ndata++;
1002 nlen--;
1003 if (count == 0) {
1004 saw_root = 1;
1005 break;
1006 }
1007 if (count < 64) {
1008 INSIST(nlen >= count)((void) ((nlen >= count) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1008, isc_assertiontype_insist, "nlen >= count"), 0)))
;
1009 while (count > 0) {
1010 c = *ndata;
1011 switch (c) {
1012 /* Special modifiers in zone files. */
1013 case 0x40: /* '@' */
1014 case 0x24: /* '$' */
1015 if ((options & DNS_NAME_MASTERFILE0x02U) == 0)
1016 goto no_escape;
1017 /* FALLTHROUGH */
1018 case 0x22: /* '"' */
1019 case 0x28: /* '(' */
1020 case 0x29: /* ')' */
1021 case 0x2E: /* '.' */
1022 case 0x3B: /* ';' */
1023 case 0x5C: /* '\\' */
1024 if (trem < 2)
1025 return (ISC_R_NOSPACE19);
1026 *tdata++ = '\\';
1027 CONVERTFROMASCII(c);
1028 *tdata++ = c;
1029 ndata++;
1030 trem -= 2;
1031 nlen--;
1032 break;
1033 no_escape:
1034 default:
1035 if (c > 0x20 && c < 0x7f) {
1036 if (trem == 0)
1037 return (ISC_R_NOSPACE19);
1038 CONVERTFROMASCII(c);
1039 *tdata++ = c;
1040 ndata++;
1041 trem--;
1042 nlen--;
1043 } else {
1044 if (trem < 4)
1045 return (ISC_R_NOSPACE19);
1046 *tdata++ = 0x5c;
1047 *tdata++ = 0x30 +
1048 ((c / 100) % 10);
1049 *tdata++ = 0x30 +
1050 ((c / 10) % 10);
1051 *tdata++ = 0x30 + (c % 10);
1052 trem -= 4;
1053 ndata++;
1054 nlen--;
1055 }
1056 }
1057 count--;
1058 }
1059 } else {
1060 FATAL_ERRORisc_error_fatal(__FILE__"/usr/src/usr.bin/dig/lib/dns/name.c", __LINE__1060,
1061 "Unexpected label type %02x", count);
1062 /* NOTREACHED */
1063 }
1064
1065 /*
1066 * The following assumes names are absolute. If not, we
1067 * fix things up later. Note that this means that in some
1068 * cases one more byte of text buffer is required than is
1069 * needed in the final output.
1070 */
1071 if (trem == 0)
1072 return (ISC_R_NOSPACE19);
1073 *tdata++ = '.';
1074 trem--;
1075 }
1076
1077 if (nlen != 0 && trem == 0)
1078 return (ISC_R_NOSPACE19);
1079
1080 if (!saw_root || omit_final_dot)
1081 trem++;
1082
1083 isc_buffer_addisc__buffer_add(target, tlen - trem);
1084
1085 return (ISC_R_SUCCESS0);
1086}
1087
1088isc_result_t
1089dns_name_downcase(dns_name_t *source, dns_name_t *name, isc_buffer_t *target) {
1090 unsigned char *sndata, *ndata;
1091 unsigned int nlen, count, labels;
1092 isc_buffer_t buffer;
1093
1094 /*
1095 * Downcase 'source'.
1096 */
1097
1098 if (source == name) {
1099 REQUIRE((name->attributes & DNS_NAMEATTR_READONLY) == 0)((void) (((name->attributes & 0x00000002) == 0) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 1099, isc_assertiontype_require
, "(name->attributes & 0x00000002) == 0"), 0)))
;
1100 isc_buffer_initisc__buffer_init(&buffer, source->ndata, source->length);
1101 target = &buffer;
1102 ndata = source->ndata;
1103 } else {
1104 REQUIRE(BINDABLE(name))((void) ((((name->attributes & (0x00000002|0x00000004)
) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1104, isc_assertiontype_require, "((name->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
1105 if (target == NULL((void *)0)) {
1106 target = name->buffer;
1107 isc_buffer_clearisc__buffer_clear(name->buffer);
1108 }
1109 ndata = (unsigned char *)target->base + target->used;
1110 name->ndata = ndata;
1111 }
1112
1113 sndata = source->ndata;
1114 nlen = source->length;
1115 labels = source->labels;
1116
1117 if (nlen > (target->length - target->used)) {
1118 MAKE_EMPTY(name)do { name->ndata = ((void *)0); name->length = 0; name->
labels = 0; name->attributes &= ~0x00000001; } while (
0);
;
1119 return (ISC_R_NOSPACE19);
1120 }
1121
1122 while (labels > 0 && nlen > 0) {
1123 labels--;
1124 count = *sndata++;
1125 *ndata++ = count;
1126 nlen--;
1127 if (count < 64) {
1128 INSIST(nlen >= count)((void) ((nlen >= count) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1128, isc_assertiontype_insist, "nlen >= count"), 0)))
;
1129 while (count > 0) {
1130 *ndata++ = maptolower[(*sndata++)];
1131 nlen--;
1132 count--;
1133 }
1134 } else {
1135 FATAL_ERRORisc_error_fatal(__FILE__"/usr/src/usr.bin/dig/lib/dns/name.c", __LINE__1135,
1136 "Unexpected label type %02x", count);
1137 /* Does not return. */
1138 }
1139 }
1140
1141 if (source != name) {
1142 name->labels = source->labels;
1143 name->length = source->length;
1144 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE0x00000001) != 0)
1145 name->attributes = DNS_NAMEATTR_ABSOLUTE0x00000001;
1146 else
1147 name->attributes = 0;
1148 if (name->labels > 0 && name->offsets != NULL((void *)0))
1149 set_offsets(name, name->offsets, NULL((void *)0));
1150 }
1151
1152 isc_buffer_addisc__buffer_add(target, name->length);
1153
1154 return (ISC_R_SUCCESS0);
1155}
1156
1157static void
1158set_offsets(const dns_name_t *name, unsigned char *offsets,
1159 dns_name_t *set_name)
1160{
1161 unsigned int offset, count, length, nlabels;
1162 unsigned char *ndata;
1163 int absolute;
1164
1165 ndata = name->ndata;
1166 length = name->length;
1167 offset = 0;
1168 nlabels = 0;
1169 absolute = 0;
1170 while (offset != length) {
1171 INSIST(nlabels < 128)((void) ((nlabels < 128) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1171, isc_assertiontype_insist, "nlabels < 128"), 0)))
;
1172 offsets[nlabels++] = offset;
1173 count = *ndata++;
1174 offset++;
1175 INSIST(count <= 63)((void) ((count <= 63) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1175, isc_assertiontype_insist, "count <= 63"), 0)))
;
1176 offset += count;
1177 ndata += count;
1178 INSIST(offset <= length)((void) ((offset <= length) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1178, isc_assertiontype_insist, "offset <= length"), 0))
)
;
1179 if (count == 0) {
1180 absolute = 1;
1181 break;
1182 }
1183 }
1184 if (set_name != NULL((void *)0)) {
1185 INSIST(set_name == name)((void) ((set_name == name) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1185, isc_assertiontype_insist, "set_name == name"), 0)))
;
1186
1187 set_name->labels = nlabels;
1188 set_name->length = offset;
1189 if (absolute)
1190 set_name->attributes |= DNS_NAMEATTR_ABSOLUTE0x00000001;
1191 else
1192 set_name->attributes &= ~DNS_NAMEATTR_ABSOLUTE0x00000001;
1193 }
1194 INSIST(nlabels == name->labels)((void) ((nlabels == name->labels) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 1194, isc_assertiontype_insist
, "nlabels == name->labels"), 0)))
;
1195 INSIST(offset == name->length)((void) ((offset == name->length) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 1195, isc_assertiontype_insist
, "offset == name->length"), 0)))
;
1196}
1197
1198isc_result_t
1199dns_name_fromwire(dns_name_t *name, isc_buffer_t *source,
1200 dns_decompress_t *dctx, unsigned int options,
1201 isc_buffer_t *target)
1202{
1203 unsigned char *cdata, *ndata;
1204 unsigned int cused; /* Bytes of compressed name data used */
1205 unsigned int nused, labels, n, nmax;
1206 unsigned int current, new_current, biggest_pointer;
1207 int done;
1208 fw_state state = fw_start;
1209 unsigned int c;
1210 unsigned char *offsets;
1211 dns_offsets_t odata;
1212 int downcase;
1213 int seen_pointer;
1214
1215 /*
1216 * Copy the possibly-compressed name at source into target,
1217 * decompressing it. Loop prevention is performed by checking
1218 * the new pointer against biggest_pointer.
1219 */
1220
1221 downcase = (options & DNS_NAME_DOWNCASE0x0001) != 0;
1
Assuming the condition is false
1222
1223 if (target == NULL((void *)0) && name->buffer != NULL((void *)0)) {
2
Assuming 'target' is equal to NULL
3
Assuming field 'buffer' is equal to NULL
4
Taking false branch
1224 target = name->buffer;
1225 isc_buffer_clearisc__buffer_clear(target);
1226 }
1227
1228 REQUIRE(dctx != NULL)((void) ((dctx != ((void *)0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1228, isc_assertiontype_require, "dctx != ((void *)0)"), 0)
))
;
5
Assuming 'dctx' is not equal to null
1229 REQUIRE(BINDABLE(name))((void) ((((name->attributes & (0x00000002|0x00000004)
) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1229, isc_assertiontype_require, "((name->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
6
Assuming the condition is true
1230
1231 INIT_OFFSETS(name, offsets, odata)if ((name)->offsets != ((void *)0)) offsets = (name)->offsets
; else offsets = (odata);
;
7
Assuming field 'offsets' is equal to null
8
Taking false branch
1232
1233 /*
1234 * Make 'name' empty in case of failure.
1235 */
1236 MAKE_EMPTY(name)do { name->ndata = ((void *)0); name->length = 0; name->
labels = 0; name->attributes &= ~0x00000001; } while (
0);
;
9
Loop condition is false. Exiting loop
1237
1238 /*
1239 * Initialize things to make the compiler happy; they're not required.
1240 */
1241 n = 0;
1242 new_current = 0;
1243
1244 /*
1245 * Set up.
1246 */
1247 labels = 0;
1248 done = 0;
1249
1250 ndata = isc_buffer_used(target)((void *)((unsigned char *)(target)->base + (target)->used
))
;
10
Access to field 'base' results in a dereference of a null pointer (loaded from variable 'target')
1251 nused = 0;
1252 seen_pointer = 0;
1253
1254 /*
1255 * Find the maximum number of uncompressed target name
1256 * bytes we are willing to generate. This is the smaller
1257 * of the available target buffer length and the
1258 * maximum legal domain name length (255).
1259 */
1260 nmax = isc_buffer_availablelength(target)((target)->length - (target)->used);
1261 if (nmax > DNS_NAME_MAXWIRE255)
1262 nmax = DNS_NAME_MAXWIRE255;
1263
1264 cdata = isc_buffer_current(source)((void *)((unsigned char *)(source)->base + (source)->current
))
;
1265 cused = 0;
1266
1267 current = source->current;
1268 biggest_pointer = current;
1269
1270 /*
1271 * Note: The following code is not optimized for speed, but
1272 * rather for correctness. Speed will be addressed in the future.
1273 */
1274
1275 while (current < source->active && !done) {
1276 c = *cdata++;
1277 current++;
1278 if (!seen_pointer)
1279 cused++;
1280
1281 switch (state) {
1282 case fw_start:
1283 if (c < 64) {
1284 offsets[labels] = nused;
1285 labels++;
1286 if (nused + c + 1 > nmax)
1287 goto full;
1288 nused += c + 1;
1289 *ndata++ = c;
1290 if (c == 0)
1291 done = 1;
1292 n = c;
1293 state = fw_ordinary;
1294 } else if (c >= 128 && c < 192) {
1295 /*
1296 * 14 bit local compression pointer.
1297 * Local compression is no longer an
1298 * IETF draft.
1299 */
1300 return (DNS_R_BADLABELTYPE(((1) << 16) + 8));
1301 } else if (c >= 192) {
1302 /*
1303 * Ordinary 14-bit pointer.
1304 */
1305 if ((dctx->allowed & DNS_COMPRESS_GLOBAL140x01) ==
1306 0)
1307 return (DNS_R_DISALLOWED(((1) << 16) + 11));
1308 new_current = c & 0x3F;
1309 state = fw_newcurrent;
1310 } else
1311 return (DNS_R_BADLABELTYPE(((1) << 16) + 8));
1312 break;
1313 case fw_ordinary:
1314 if (downcase)
1315 c = maptolower[c];
1316 *ndata++ = c;
1317 n--;
1318 if (n == 0)
1319 state = fw_start;
1320 break;
1321 case fw_newcurrent:
1322 new_current *= 256;
1323 new_current += c;
1324 if (new_current >= biggest_pointer)
1325 return (DNS_R_BADPOINTER(((1) << 16) + 9));
1326 biggest_pointer = new_current;
1327 current = new_current;
1328 cdata = (unsigned char *)source->base + current;
1329 seen_pointer = 1;
1330 state = fw_start;
1331 break;
1332 default:
1333 FATAL_ERRORisc_error_fatal(__FILE__"/usr/src/usr.bin/dig/lib/dns/name.c", __LINE__1333,
1334 "Unknown state %d", state);
1335 /* Does not return. */
1336 }
1337 }
1338
1339 if (!done)
1340 return (ISC_R_UNEXPECTEDEND24);
1341
1342 name->ndata = (unsigned char *)target->base + target->used;
1343 name->labels = labels;
1344 name->length = nused;
1345 name->attributes |= DNS_NAMEATTR_ABSOLUTE0x00000001;
1346
1347 isc_buffer_forwardisc__buffer_forward(source, cused);
1348 isc_buffer_addisc__buffer_add(target, name->length);
1349
1350 return (ISC_R_SUCCESS0);
1351
1352 full:
1353 if (nmax == DNS_NAME_MAXWIRE255)
1354 /*
1355 * The name did not fit even though we had a buffer
1356 * big enough to fit a maximum-length name.
1357 */
1358 return (DNS_R_NAMETOOLONG(((1) << 16) + 22));
1359 else
1360 /*
1361 * The name might fit if only the caller could give us a
1362 * big enough buffer.
1363 */
1364 return (ISC_R_NOSPACE19);
1365}
1366
1367isc_result_t
1368dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
1369 isc_buffer_t *target)
1370{
1371 unsigned int methods;
1372 uint16_t offset;
1373 dns_name_t gp; /* Global compression prefix */
1374 int gf; /* Global compression target found */
1375 uint16_t go; /* Global compression offset */
1376 dns_offsets_t clo;
1377 dns_name_t clname;
1378
1379 /*
1380 * Convert 'name' into wire format, compressing it as specified by the
1381 * compression context 'cctx', and storing the result in 'target'.
1382 */
1383
1384 REQUIRE(cctx != NULL)((void) ((cctx != ((void *)0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1384, isc_assertiontype_require, "cctx != ((void *)0)"), 0)
))
;
1385
1386 /*
1387 * If 'name' doesn't have an offsets table, make a clone which
1388 * has one.
1389 */
1390 if (name->offsets == NULL((void *)0)) {
1391 dns_name_init(&clname, clo);
1392 dns_name_clone(name, &clname);
1393 name = &clname;
1394 }
1395 dns_name_init(&gp, NULL((void *)0));
1396
1397 offset = target->used; /*XXX*/
1398
1399 methods = dns_compress_getmethods(cctx);
1400
1401 if ((name->attributes & DNS_NAMEATTR_NOCOMPRESS0x00000010) == 0 &&
1402 (methods & DNS_COMPRESS_GLOBAL140x01) != 0)
1403 gf = dns_compress_findglobal(cctx, name, &gp, &go);
1404 else
1405 gf = 0;
1406
1407 /*
1408 * If the offset is too high for 14 bit global compression, we're
1409 * out of luck.
1410 */
1411 if (gf && go >= 0x4000)
1412 gf = 0;
1413
1414 /*
1415 * Will the compression pointer reduce the message size?
1416 */
1417 if (gf && (gp.length + 2) >= name->length)
1418 gf = 0;
1419
1420 if (gf) {
1421 if (target->length - target->used < gp.length)
1422 return (ISC_R_NOSPACE19);
1423 if (gp.length != 0) {
1424 unsigned char *base = target->base;
1425 (void)memmove(base + target->used, gp.ndata,
1426 (size_t)gp.length);
1427 }
1428 isc_buffer_addisc__buffer_add(target, gp.length);
1429 go |= 0xc000;
1430 if (target->length - target->used < 2)
1431 return (ISC_R_NOSPACE19);
1432 isc_buffer_putuint16isc__buffer_putuint16(target, go);
1433 if (gp.length != 0)
1434 dns_compress_add(cctx, name, &gp, offset);
1435 } else {
1436 if (target->length - target->used < name->length)
1437 return (ISC_R_NOSPACE19);
1438 if (name->length != 0) {
1439 unsigned char *base = target->base;
1440 (void)memmove(base + target->used, name->ndata,
1441 (size_t)name->length);
1442 }
1443 isc_buffer_addisc__buffer_add(target, name->length);
1444 dns_compress_add(cctx, name, name, offset);
1445 }
1446 return (ISC_R_SUCCESS0);
1447}
1448
1449isc_result_t
1450dns_name_concatenate(dns_name_t *prefix, dns_name_t *suffix, dns_name_t *name,
1451 isc_buffer_t *target)
1452{
1453 unsigned char *ndata, *offsets;
1454 unsigned int nrem, labels, prefix_length, length;
1455 int copy_prefix = 1;
1456 int copy_suffix = 1;
1457 int absolute = 0;
1458 dns_name_t tmp_name;
1459 dns_offsets_t odata;
1460
1461 /*
1462 * Concatenate 'prefix' and 'suffix'.
1463 */
1464
1465 if (prefix == NULL((void *)0) || prefix->labels == 0)
1466 copy_prefix = 0;
1467 if (suffix == NULL((void *)0) || suffix->labels == 0)
1468 copy_suffix = 0;
1469 if (copy_prefix &&
1470 (prefix->attributes & DNS_NAMEATTR_ABSOLUTE0x00000001) != 0) {
1471 absolute = 1;
1472 REQUIRE(!copy_suffix)((void) ((!copy_suffix) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1472, isc_assertiontype_require, "!copy_suffix"), 0)))
;
1473 }
1474 if (name == NULL((void *)0)) {
1475 dns_name_init(&tmp_name, odata);
1476 name = &tmp_name;
1477 }
1478 if (target == NULL((void *)0)) {
1479 INSIST(name->buffer != NULL)((void) ((name->buffer != ((void *)0)) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 1479, isc_assertiontype_insist
, "name->buffer != ((void *)0)"), 0)))
;
1480 target = name->buffer;
1481 isc_buffer_clearisc__buffer_clear(name->buffer);
1482 }
1483
1484 REQUIRE(BINDABLE(name))((void) ((((name->attributes & (0x00000002|0x00000004)
) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1484, isc_assertiontype_require, "((name->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
1485
1486 /*
1487 * Set up.
1488 */
1489 nrem = target->length - target->used;
1490 ndata = (unsigned char *)target->base + target->used;
1491 if (nrem > DNS_NAME_MAXWIRE255)
1492 nrem = DNS_NAME_MAXWIRE255;
1493 length = 0;
1494 prefix_length = 0;
1495 labels = 0;
1496 if (copy_prefix) {
1497 prefix_length = prefix->length;
1498 length += prefix_length;
1499 labels += prefix->labels;
1500 }
1501 if (copy_suffix) {
1502 length += suffix->length;
1503 labels += suffix->labels;
1504 }
1505 if (length > DNS_NAME_MAXWIRE255) {
1506 MAKE_EMPTY(name)do { name->ndata = ((void *)0); name->length = 0; name->
labels = 0; name->attributes &= ~0x00000001; } while (
0);
;
1507 return (DNS_R_NAMETOOLONG(((1) << 16) + 22));
1508 }
1509 if (length > nrem) {
1510 MAKE_EMPTY(name)do { name->ndata = ((void *)0); name->length = 0; name->
labels = 0; name->attributes &= ~0x00000001; } while (
0);
;
1511 return (ISC_R_NOSPACE19);
1512 }
1513
1514 if (copy_suffix) {
1515 if ((suffix->attributes & DNS_NAMEATTR_ABSOLUTE0x00000001) != 0)
1516 absolute = 1;
1517 memmove(ndata + prefix_length, suffix->ndata, suffix->length);
1518 }
1519
1520 /*
1521 * If 'prefix' and 'name' are the same object, and the object has
1522 * a dedicated buffer, and we're using it, then we don't have to
1523 * copy anything.
1524 */
1525 if (copy_prefix && (prefix != name || prefix->buffer != target))
1526 memmove(ndata, prefix->ndata, prefix_length);
1527
1528 name->ndata = ndata;
1529 name->labels = labels;
1530 name->length = length;
1531 if (absolute)
1532 name->attributes = DNS_NAMEATTR_ABSOLUTE0x00000001;
1533 else
1534 name->attributes = 0;
1535
1536 if (name->labels > 0 && name->offsets != NULL((void *)0)) {
1537 INIT_OFFSETS(name, offsets, odata)if ((name)->offsets != ((void *)0)) offsets = (name)->offsets
; else offsets = (odata);
;
1538 set_offsets(name, offsets, NULL((void *)0));
1539 }
1540
1541 isc_buffer_addisc__buffer_add(target, name->length);
1542
1543 return (ISC_R_SUCCESS0);
1544}
1545
1546isc_result_t
1547dns_name_dup(const dns_name_t *source,
1548 dns_name_t *target)
1549{
1550 /*
1551 * Make 'target' a dynamically allocated copy of 'source'.
1552 */
1553
1554 REQUIRE(source->length > 0)((void) ((source->length > 0) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 1554, isc_assertiontype_require
, "source->length > 0"), 0)))
;
1555 REQUIRE(BINDABLE(target))((void) ((((target->attributes & (0x00000002|0x00000004
)) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1555, isc_assertiontype_require, "((target->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
1556
1557 /*
1558 * Make 'target' empty in case of failure.
1559 */
1560 MAKE_EMPTY(target)do { target->ndata = ((void *)0); target->length = 0; target
->labels = 0; target->attributes &= ~0x00000001; } while
(0);
;
1561
1562 target->ndata = malloc(source->length);
1563 if (target->ndata == NULL((void *)0))
1564 return (ISC_R_NOMEMORY1);
1565
1566 memmove(target->ndata, source->ndata, source->length);
1567
1568 target->length = source->length;
1569 target->labels = source->labels;
1570 target->attributes = DNS_NAMEATTR_DYNAMIC0x00000004;
1571 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE0x00000001) != 0)
1572 target->attributes |= DNS_NAMEATTR_ABSOLUTE0x00000001;
1573 if (target->offsets != NULL((void *)0)) {
1574 if (source->offsets != NULL((void *)0))
1575 memmove(target->offsets, source->offsets,
1576 source->labels);
1577 else
1578 set_offsets(target, target->offsets, NULL((void *)0));
1579 }
1580
1581 return (ISC_R_SUCCESS0);
1582}
1583
1584isc_result_t
1585dns_name_dupwithoffsets(dns_name_t *source,
1586 dns_name_t *target)
1587{
1588 /*
1589 * Make 'target' a read-only dynamically allocated copy of 'source'.
1590 * 'target' will also have a dynamically allocated offsets table.
1591 */
1592
1593 REQUIRE(source->length > 0)((void) ((source->length > 0) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 1593, isc_assertiontype_require
, "source->length > 0"), 0)))
;
1594 REQUIRE(BINDABLE(target))((void) ((((target->attributes & (0x00000002|0x00000004
)) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1594, isc_assertiontype_require, "((target->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
1595 REQUIRE(target->offsets == NULL)((void) ((target->offsets == ((void *)0)) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 1595, isc_assertiontype_require
, "target->offsets == ((void *)0)"), 0)))
;
1596
1597 /*
1598 * Make 'target' empty in case of failure.
1599 */
1600 MAKE_EMPTY(target)do { target->ndata = ((void *)0); target->length = 0; target
->labels = 0; target->attributes &= ~0x00000001; } while
(0);
;
1601
1602 target->ndata = malloc(source->length + source->labels);
1603 if (target->ndata == NULL((void *)0))
1604 return (ISC_R_NOMEMORY1);
1605
1606 memmove(target->ndata, source->ndata, source->length);
1607
1608 target->length = source->length;
1609 target->labels = source->labels;
1610 target->attributes = DNS_NAMEATTR_DYNAMIC0x00000004 | DNS_NAMEATTR_DYNOFFSETS0x00000008 |
1611 DNS_NAMEATTR_READONLY0x00000002;
1612 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE0x00000001) != 0)
1613 target->attributes |= DNS_NAMEATTR_ABSOLUTE0x00000001;
1614 target->offsets = target->ndata + source->length;
1615 if (source->offsets != NULL((void *)0))
1616 memmove(target->offsets, source->offsets, source->labels);
1617 else
1618 set_offsets(target, target->offsets, NULL((void *)0));
1619
1620 return (ISC_R_SUCCESS0);
1621}
1622
1623void
1624dns_name_free(dns_name_t *name) {
1625 /*
1626 * Free 'name'.
1627 */
1628
1629 REQUIRE((name->attributes & DNS_NAMEATTR_DYNAMIC) != 0)((void) (((name->attributes & 0x00000004) != 0) || ((isc_assertion_failed
)("/usr/src/usr.bin/dig/lib/dns/name.c", 1629, isc_assertiontype_require
, "(name->attributes & 0x00000004) != 0"), 0)))
;
1630
1631 free(name->ndata);
1632 dns_name_invalidate(name);
1633}
1634
1635int
1636dns_name_dynamic(dns_name_t *name) {
1637
1638 /*
1639 * Returns whether there is dynamic memory associated with this name.
1640 */
1641
1642 return ((name->attributes & DNS_NAMEATTR_DYNAMIC0x00000004) != 0 ?
1643 1 : 0);
1644}
1645
1646void
1647dns_name_format(dns_name_t *name, char *cp, unsigned int size) {
1648 isc_result_t result;
1649 isc_buffer_t buf;
1650
1651 REQUIRE(size > 0)((void) ((size > 0) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1651, isc_assertiontype_require, "size > 0"), 0)))
;
1652
1653 /*
1654 * Leave room for null termination after buffer.
1655 */
1656 isc_buffer_initisc__buffer_init(&buf, cp, size - 1);
1657 result = dns_name_totext(name, 1, &buf);
1658 if (result == ISC_R_SUCCESS0) {
1659 /*
1660 * Null terminate.
1661 */
1662 isc_region_t r;
1663 isc_buffer_usedregionisc__buffer_usedregion(&buf, &r);
1664 ((char *) r.base)[r.length] = '\0';
1665
1666 } else
1667 snprintf(cp, size, "<unknown>");
1668}
1669
1670/*
1671 * dns_name_fromstring() -- convert directly from a string to a name,
1672 * allocating memory as needed
1673 */
1674isc_result_t
1675dns_name_fromstring2(dns_name_t *target, const char *src,
1676 const dns_name_t *origin, unsigned int options)
1677{
1678 isc_result_t result;
1679 isc_buffer_t buf;
1680 dns_fixedname_t fn;
1681 dns_name_t *name;
1682
1683 REQUIRE(src != NULL)((void) ((src != ((void *)0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1683, isc_assertiontype_require, "src != ((void *)0)"), 0))
)
;
1684
1685 isc_buffer_initisc__buffer_init(&buf, (void *)src, strlen(src));
1686 isc_buffer_addisc__buffer_add(&buf, strlen(src));
1687 if (BINDABLE(target)((target->attributes & (0x00000002|0x00000004)) == 0) && target->buffer != NULL((void *)0))
1688 name = target;
1689 else {
1690 dns_fixedname_init(&fn)do { dns_name_init(&((&fn)->name), (&fn)->offsets
); isc__buffer_init(&((&fn)->buffer), (&fn)->
data, 255); dns_name_setbuffer(&((&fn)->name), &
((&fn)->buffer)); } while (0)
;
1691 name = dns_fixedname_name(&fn)(&((&fn)->name));
1692 }
1693
1694 result = dns_name_fromtext(name, &buf, origin, options, NULL((void *)0));
1695 if (result != ISC_R_SUCCESS0)
1696 return (result);
1697
1698 if (name != target)
1699 result = dns_name_dupwithoffsets(name, target);
1700 return (result);
1701}
1702
1703isc_result_t
1704dns_name_copy(dns_name_t *source, dns_name_t *dest, isc_buffer_t *target) {
1705 unsigned char *ndata;
1706
1707 /*
1708 * Make dest a copy of source.
1709 */
1710
1711 REQUIRE(target != NULL || dest->buffer != NULL)((void) ((target != ((void *)0) || dest->buffer != ((void *
)0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1711, isc_assertiontype_require, "target != ((void *)0) || dest->buffer != ((void *)0)"
), 0)))
;
1712
1713 if (target == NULL((void *)0)) {
1714 target = dest->buffer;
1715 isc_buffer_clearisc__buffer_clear(dest->buffer);
1716 }
1717
1718 REQUIRE(BINDABLE(dest))((void) ((((dest->attributes & (0x00000002|0x00000004)
) == 0)) || ((isc_assertion_failed)("/usr/src/usr.bin/dig/lib/dns/name.c"
, 1718, isc_assertiontype_require, "((dest->attributes & (0x00000002|0x00000004)) == 0)"
), 0)))
;
1719
1720 /*
1721 * Set up.
1722 */
1723 if (target->length - target->used < source->length)
1724 return (ISC_R_NOSPACE19);
1725
1726 ndata = (unsigned char *)target->base + target->used;
1727 dest->ndata = target->base;
1728
1729 if (source->length != 0)
1730 memmove(ndata, source->ndata, source->length);
1731
1732 dest->ndata = ndata;
1733 dest->labels = source->labels;
1734 dest->length = source->length;
1735 if ((source->attributes & DNS_NAMEATTR_ABSOLUTE0x00000001) != 0)
1736 dest->attributes = DNS_NAMEATTR_ABSOLUTE0x00000001;
1737 else
1738 dest->attributes = 0;
1739
1740 if (dest->labels > 0 && dest->offsets != NULL((void *)0)) {
1741 if (source->offsets != NULL((void *)0))
1742 memmove(dest->offsets, source->offsets, source->labels);
1743 else
1744 set_offsets(dest, dest->offsets, NULL((void *)0));
1745 }
1746
1747 isc_buffer_addisc__buffer_add(target, dest->length);
1748
1749 return (ISC_R_SUCCESS0);
1750}