Remove building with NOCRYPTO option
[minix.git] / external / bsd / bind / dist / lib / dns / rdata / generic / naptr_35.c
blob664b383b3eeb6399a6cc8230ec51d124a241405b
1 /* $NetBSD: naptr_35.c,v 1.1.1.6 2014/12/10 03:34:42 christos Exp $ */
3 /*
4 * Copyright (C) 2004, 2005, 2007-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id */
22 /* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */
24 /* RFC2915 */
26 #ifndef RDATA_GENERIC_NAPTR_35_C
27 #define RDATA_GENERIC_NAPTR_35_C
29 #define RRTYPE_NAPTR_ATTRIBUTES (0)
31 #include <isc/regex.h>
34 * Check the wire format of the Regexp field.
35 * Don't allow embeded NUL's.
37 static inline isc_result_t
38 txt_valid_regex(const unsigned char *txt) {
39 unsigned int nsub = 0;
40 char regex[256];
41 char *cp;
42 isc_boolean_t flags = ISC_FALSE;
43 isc_boolean_t replace = ISC_FALSE;
44 unsigned char c;
45 unsigned char delim;
46 unsigned int len;
47 int n;
49 len = *txt++;
50 if (len == 0U)
51 return (ISC_R_SUCCESS);
53 delim = *txt++;
54 len--;
57 * Digits, backslash and flags can't be delimiters.
59 switch (delim) {
60 case '0': case '1': case '2': case '3': case '4':
61 case '5': case '6': case '7': case '8': case '9':
62 case '\\': case 'i': case 0:
63 return (DNS_R_SYNTAX);
66 cp = regex;
67 while (len-- > 0) {
68 c = *txt++;
69 if (c == 0)
70 return (DNS_R_SYNTAX);
71 if (c == delim && !replace) {
72 replace = ISC_TRUE;
73 continue;
74 } else if (c == delim && !flags) {
75 flags = ISC_TRUE;
76 continue;
77 } else if (c == delim)
78 return (DNS_R_SYNTAX);
80 * Flags are not escaped.
82 if (flags) {
83 switch (c) {
84 case 'i':
85 continue;
86 default:
87 return (DNS_R_SYNTAX);
90 if (!replace)
91 *cp++ = c;
92 if (c == '\\') {
93 if (len == 0)
94 return (DNS_R_SYNTAX);
95 c = *txt++;
96 if (c == 0)
97 return (DNS_R_SYNTAX);
98 len--;
99 if (replace)
100 switch (c) {
101 case '0': return (DNS_R_SYNTAX);
102 case '1': if (nsub < 1) nsub = 1; break;
103 case '2': if (nsub < 2) nsub = 2; break;
104 case '3': if (nsub < 3) nsub = 3; break;
105 case '4': if (nsub < 4) nsub = 4; break;
106 case '5': if (nsub < 5) nsub = 5; break;
107 case '6': if (nsub < 6) nsub = 6; break;
108 case '7': if (nsub < 7) nsub = 7; break;
109 case '8': if (nsub < 8) nsub = 8; break;
110 case '9': if (nsub < 9) nsub = 9; break;
112 if (!replace)
113 *cp++ = c;
116 if (!flags)
117 return (DNS_R_SYNTAX);
118 *cp = '\0';
119 n = isc_regex_validate(regex);
120 if (n < 0 || nsub > (unsigned int)n)
121 return (DNS_R_SYNTAX);
122 return (ISC_R_SUCCESS);
125 static inline isc_result_t
126 fromtext_naptr(ARGS_FROMTEXT) {
127 isc_token_t token;
128 dns_name_t name;
129 isc_buffer_t buffer;
130 unsigned char *regex;
132 REQUIRE(type == 35);
134 UNUSED(type);
135 UNUSED(rdclass);
136 UNUSED(callbacks);
139 * Order.
141 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
142 ISC_FALSE));
143 if (token.value.as_ulong > 0xffffU)
144 RETTOK(ISC_R_RANGE);
145 RETERR(uint16_tobuffer(token.value.as_ulong, target));
148 * Preference.
150 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
151 ISC_FALSE));
152 if (token.value.as_ulong > 0xffffU)
153 RETTOK(ISC_R_RANGE);
154 RETERR(uint16_tobuffer(token.value.as_ulong, target));
157 * Flags.
159 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
160 ISC_FALSE));
161 RETTOK(txt_fromtext(&token.value.as_textregion, target));
164 * Service.
166 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
167 ISC_FALSE));
168 RETTOK(txt_fromtext(&token.value.as_textregion, target));
171 * Regexp.
173 regex = isc_buffer_used(target);
174 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
175 ISC_FALSE));
176 RETTOK(txt_fromtext(&token.value.as_textregion, target));
177 RETTOK(txt_valid_regex(regex));
180 * Replacement.
182 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
183 ISC_FALSE));
184 dns_name_init(&name, NULL);
185 buffer_fromregion(&buffer, &token.value.as_region);
186 origin = (origin != NULL) ? origin : dns_rootname;
187 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
188 return (ISC_R_SUCCESS);
191 static inline isc_result_t
192 totext_naptr(ARGS_TOTEXT) {
193 isc_region_t region;
194 dns_name_t name;
195 dns_name_t prefix;
196 isc_boolean_t sub;
197 char buf[sizeof("64000")];
198 unsigned short num;
200 REQUIRE(rdata->type == 35);
201 REQUIRE(rdata->length != 0);
203 dns_name_init(&name, NULL);
204 dns_name_init(&prefix, NULL);
206 dns_rdata_toregion(rdata, &region);
209 * Order.
211 num = uint16_fromregion(&region);
212 isc_region_consume(&region, 2);
213 sprintf(buf, "%u", num);
214 RETERR(str_totext(buf, target));
215 RETERR(str_totext(" ", target));
218 * Preference.
220 num = uint16_fromregion(&region);
221 isc_region_consume(&region, 2);
222 sprintf(buf, "%u", num);
223 RETERR(str_totext(buf, target));
224 RETERR(str_totext(" ", target));
227 * Flags.
229 RETERR(txt_totext(&region, ISC_TRUE, target));
230 RETERR(str_totext(" ", target));
233 * Service.
235 RETERR(txt_totext(&region, ISC_TRUE, target));
236 RETERR(str_totext(" ", target));
239 * Regexp.
241 RETERR(txt_totext(&region, ISC_TRUE, target));
242 RETERR(str_totext(" ", target));
245 * Replacement.
247 dns_name_fromregion(&name, &region);
248 sub = name_prefix(&name, tctx->origin, &prefix);
249 return (dns_name_totext(&prefix, sub, target));
252 static inline isc_result_t
253 fromwire_naptr(ARGS_FROMWIRE) {
254 dns_name_t name;
255 isc_region_t sr;
256 unsigned char *regex;
258 REQUIRE(type == 35);
260 UNUSED(type);
261 UNUSED(rdclass);
263 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
265 dns_name_init(&name, NULL);
268 * Order, preference.
270 isc_buffer_activeregion(source, &sr);
271 if (sr.length < 4)
272 return (ISC_R_UNEXPECTEDEND);
273 RETERR(mem_tobuffer(target, sr.base, 4));
274 isc_buffer_forward(source, 4);
277 * Flags.
279 RETERR(txt_fromwire(source, target));
282 * Service.
284 RETERR(txt_fromwire(source, target));
287 * Regexp.
289 regex = isc_buffer_used(target);
290 RETERR(txt_fromwire(source, target));
291 RETERR(txt_valid_regex(regex));
294 * Replacement.
296 return (dns_name_fromwire(&name, source, dctx, options, target));
299 static inline isc_result_t
300 towire_naptr(ARGS_TOWIRE) {
301 dns_name_t name;
302 dns_offsets_t offsets;
303 isc_region_t sr;
305 REQUIRE(rdata->type == 35);
306 REQUIRE(rdata->length != 0);
308 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
310 * Order, preference.
312 dns_rdata_toregion(rdata, &sr);
313 RETERR(mem_tobuffer(target, sr.base, 4));
314 isc_region_consume(&sr, 4);
317 * Flags.
319 RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
320 isc_region_consume(&sr, sr.base[0] + 1);
323 * Service.
325 RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
326 isc_region_consume(&sr, sr.base[0] + 1);
329 * Regexp.
331 RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
332 isc_region_consume(&sr, sr.base[0] + 1);
335 * Replacement.
337 dns_name_init(&name, offsets);
338 dns_name_fromregion(&name, &sr);
339 return (dns_name_towire(&name, cctx, target));
342 static inline int
343 compare_naptr(ARGS_COMPARE) {
344 dns_name_t name1;
345 dns_name_t name2;
346 isc_region_t region1;
347 isc_region_t region2;
348 int order, len;
350 REQUIRE(rdata1->type == rdata2->type);
351 REQUIRE(rdata1->rdclass == rdata2->rdclass);
352 REQUIRE(rdata1->type == 35);
353 REQUIRE(rdata1->length != 0);
354 REQUIRE(rdata2->length != 0);
356 dns_rdata_toregion(rdata1, &region1);
357 dns_rdata_toregion(rdata2, &region2);
360 * Order, preference.
362 order = memcmp(region1.base, region2.base, 4);
363 if (order != 0)
364 return (order < 0 ? -1 : 1);
365 isc_region_consume(&region1, 4);
366 isc_region_consume(&region2, 4);
369 * Flags.
371 len = ISC_MIN(region1.base[0], region2.base[0]);
372 order = memcmp(region1.base, region2.base, len + 1);
373 if (order != 0)
374 return (order < 0 ? -1 : 1);
375 isc_region_consume(&region1, region1.base[0] + 1);
376 isc_region_consume(&region2, region2.base[0] + 1);
379 * Service.
381 len = ISC_MIN(region1.base[0], region2.base[0]);
382 order = memcmp(region1.base, region2.base, len + 1);
383 if (order != 0)
384 return (order < 0 ? -1 : 1);
385 isc_region_consume(&region1, region1.base[0] + 1);
386 isc_region_consume(&region2, region2.base[0] + 1);
389 * Regexp.
391 len = ISC_MIN(region1.base[0], region2.base[0]);
392 order = memcmp(region1.base, region2.base, len + 1);
393 if (order != 0)
394 return (order < 0 ? -1 : 1);
395 isc_region_consume(&region1, region1.base[0] + 1);
396 isc_region_consume(&region2, region2.base[0] + 1);
399 * Replacement.
401 dns_name_init(&name1, NULL);
402 dns_name_init(&name2, NULL);
404 dns_name_fromregion(&name1, &region1);
405 dns_name_fromregion(&name2, &region2);
407 return (dns_name_rdatacompare(&name1, &name2));
410 static inline isc_result_t
411 fromstruct_naptr(ARGS_FROMSTRUCT) {
412 dns_rdata_naptr_t *naptr = source;
413 isc_region_t region;
415 REQUIRE(type == 35);
416 REQUIRE(source != NULL);
417 REQUIRE(naptr->common.rdtype == type);
418 REQUIRE(naptr->common.rdclass == rdclass);
419 REQUIRE(naptr->flags != NULL || naptr->flags_len == 0);
420 REQUIRE(naptr->service != NULL || naptr->service_len == 0);
421 REQUIRE(naptr->regexp != NULL || naptr->regexp_len == 0);
423 UNUSED(type);
424 UNUSED(rdclass);
426 RETERR(uint16_tobuffer(naptr->order, target));
427 RETERR(uint16_tobuffer(naptr->preference, target));
428 RETERR(uint8_tobuffer(naptr->flags_len, target));
429 RETERR(mem_tobuffer(target, naptr->flags, naptr->flags_len));
430 RETERR(uint8_tobuffer(naptr->service_len, target));
431 RETERR(mem_tobuffer(target, naptr->service, naptr->service_len));
432 RETERR(uint8_tobuffer(naptr->regexp_len, target));
433 RETERR(mem_tobuffer(target, naptr->regexp, naptr->regexp_len));
434 dns_name_toregion(&naptr->replacement, &region);
435 return (isc_buffer_copyregion(target, &region));
438 static inline isc_result_t
439 tostruct_naptr(ARGS_TOSTRUCT) {
440 dns_rdata_naptr_t *naptr = target;
441 isc_region_t r;
442 isc_result_t result;
443 dns_name_t name;
445 REQUIRE(rdata->type == 35);
446 REQUIRE(target != NULL);
447 REQUIRE(rdata->length != 0);
449 naptr->common.rdclass = rdata->rdclass;
450 naptr->common.rdtype = rdata->type;
451 ISC_LINK_INIT(&naptr->common, link);
453 naptr->flags = NULL;
454 naptr->service = NULL;
455 naptr->regexp = NULL;
457 dns_rdata_toregion(rdata, &r);
459 naptr->order = uint16_fromregion(&r);
460 isc_region_consume(&r, 2);
462 naptr->preference = uint16_fromregion(&r);
463 isc_region_consume(&r, 2);
465 naptr->flags_len = uint8_fromregion(&r);
466 isc_region_consume(&r, 1);
467 INSIST(naptr->flags_len <= r.length);
468 naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len);
469 if (naptr->flags == NULL)
470 goto cleanup;
471 isc_region_consume(&r, naptr->flags_len);
473 naptr->service_len = uint8_fromregion(&r);
474 isc_region_consume(&r, 1);
475 INSIST(naptr->service_len <= r.length);
476 naptr->service = mem_maybedup(mctx, r.base, naptr->service_len);
477 if (naptr->service == NULL)
478 goto cleanup;
479 isc_region_consume(&r, naptr->service_len);
481 naptr->regexp_len = uint8_fromregion(&r);
482 isc_region_consume(&r, 1);
483 INSIST(naptr->regexp_len <= r.length);
484 naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len);
485 if (naptr->regexp == NULL)
486 goto cleanup;
487 isc_region_consume(&r, naptr->regexp_len);
489 dns_name_init(&name, NULL);
490 dns_name_fromregion(&name, &r);
491 dns_name_init(&naptr->replacement, NULL);
492 result = name_duporclone(&name, mctx, &naptr->replacement);
493 if (result != ISC_R_SUCCESS)
494 goto cleanup;
495 naptr->mctx = mctx;
496 return (ISC_R_SUCCESS);
498 cleanup:
499 if (mctx != NULL && naptr->flags != NULL)
500 isc_mem_free(mctx, naptr->flags);
501 if (mctx != NULL && naptr->service != NULL)
502 isc_mem_free(mctx, naptr->service);
503 if (mctx != NULL && naptr->regexp != NULL)
504 isc_mem_free(mctx, naptr->regexp);
505 return (ISC_R_NOMEMORY);
508 static inline void
509 freestruct_naptr(ARGS_FREESTRUCT) {
510 dns_rdata_naptr_t *naptr = source;
512 REQUIRE(source != NULL);
513 REQUIRE(naptr->common.rdtype == 35);
515 if (naptr->mctx == NULL)
516 return;
518 if (naptr->flags != NULL)
519 isc_mem_free(naptr->mctx, naptr->flags);
520 if (naptr->service != NULL)
521 isc_mem_free(naptr->mctx, naptr->service);
522 if (naptr->regexp != NULL)
523 isc_mem_free(naptr->mctx, naptr->regexp);
524 dns_name_free(&naptr->replacement, naptr->mctx);
525 naptr->mctx = NULL;
528 static inline isc_result_t
529 additionaldata_naptr(ARGS_ADDLDATA) {
530 dns_name_t name;
531 dns_offsets_t offsets;
532 isc_region_t sr;
533 dns_rdatatype_t atype;
534 unsigned int i, flagslen;
535 char *cp;
537 REQUIRE(rdata->type == 35);
540 * Order, preference.
542 dns_rdata_toregion(rdata, &sr);
543 isc_region_consume(&sr, 4);
546 * Flags.
548 atype = 0;
549 flagslen = sr.base[0];
550 cp = (char *)&sr.base[1];
551 for (i = 0; i < flagslen; i++, cp++) {
552 if (*cp == 'S' || *cp == 's') {
553 atype = dns_rdatatype_srv;
554 break;
556 if (*cp == 'A' || *cp == 'a') {
557 atype = dns_rdatatype_a;
558 break;
561 isc_region_consume(&sr, flagslen + 1);
564 * Service.
566 isc_region_consume(&sr, sr.base[0] + 1);
569 * Regexp.
571 isc_region_consume(&sr, sr.base[0] + 1);
574 * Replacement.
576 dns_name_init(&name, offsets);
577 dns_name_fromregion(&name, &sr);
579 if (atype != 0)
580 return ((add)(arg, &name, atype));
582 return (ISC_R_SUCCESS);
585 static inline isc_result_t
586 digest_naptr(ARGS_DIGEST) {
587 isc_region_t r1, r2;
588 unsigned int length, n;
589 isc_result_t result;
590 dns_name_t name;
592 REQUIRE(rdata->type == 35);
594 dns_rdata_toregion(rdata, &r1);
595 r2 = r1;
596 length = 0;
599 * Order, preference.
601 length += 4;
602 isc_region_consume(&r2, 4);
605 * Flags.
607 n = r2.base[0] + 1;
608 length += n;
609 isc_region_consume(&r2, n);
612 * Service.
614 n = r2.base[0] + 1;
615 length += n;
616 isc_region_consume(&r2, n);
619 * Regexp.
621 n = r2.base[0] + 1;
622 length += n;
623 isc_region_consume(&r2, n);
626 * Digest the RR up to the replacement name.
628 r1.length = length;
629 result = (digest)(arg, &r1);
630 if (result != ISC_R_SUCCESS)
631 return (result);
634 * Replacement.
637 dns_name_init(&name, NULL);
638 dns_name_fromregion(&name, &r2);
640 return (dns_name_digest(&name, digest, arg));
643 static inline isc_boolean_t
644 checkowner_naptr(ARGS_CHECKOWNER) {
646 REQUIRE(type == 35);
648 UNUSED(name);
649 UNUSED(type);
650 UNUSED(rdclass);
651 UNUSED(wildcard);
653 return (ISC_TRUE);
656 static inline isc_boolean_t
657 checknames_naptr(ARGS_CHECKNAMES) {
659 REQUIRE(rdata->type == 35);
661 UNUSED(rdata);
662 UNUSED(owner);
663 UNUSED(bad);
665 return (ISC_TRUE);
668 static inline int
669 casecompare_naptr(ARGS_COMPARE) {
670 return (compare_naptr(rdata1, rdata2));
673 #endif /* RDATA_GENERIC_NAPTR_35_C */