Merge from vendor branch OPENSSH:
[dragonfly.git] / contrib / bind-9.3 / lib / dns / rdata / in_1 / naptr_35.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1999-2001, 2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and 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: naptr_35.c,v 1.43.2.1.2.3 2004/03/06 08:14:17 marka Exp $ */
19
20 /* Reviewed: Thu Mar 16 16:52:50 PST 2000 by bwelling */
21
22 /* RFC 2915 */
23
24 #ifndef RDATA_IN_1_NAPTR_35_C
25 #define RDATA_IN_1_NAPTR_35_C
26
27 #define RRTYPE_NAPTR_ATTRIBUTES (0)
28
29 static inline isc_result_t
30 fromtext_in_naptr(ARGS_FROMTEXT) {
31         isc_token_t token;
32         dns_name_t name;
33         isc_buffer_t buffer;
34
35         REQUIRE(type == 35);
36         REQUIRE(rdclass == 1);
37
38         UNUSED(type);
39         UNUSED(rdclass);
40         UNUSED(callbacks);
41
42         /*
43          * Order.
44          */
45         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
46                                       ISC_FALSE));
47         if (token.value.as_ulong > 0xffffU)
48                 RETTOK(ISC_R_RANGE);
49         RETERR(uint16_tobuffer(token.value.as_ulong, target));
50
51         /*
52          * Preference.
53          */
54         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
55                                       ISC_FALSE));
56         if (token.value.as_ulong > 0xffffU)
57                 RETTOK(ISC_R_RANGE);
58         RETERR(uint16_tobuffer(token.value.as_ulong, target));
59
60         /*
61          * Flags.
62          */
63         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
64                                       ISC_FALSE));
65         RETTOK(txt_fromtext(&token.value.as_textregion, target));
66
67         /*
68          * Service.
69          */
70         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
71                                       ISC_FALSE));
72         RETTOK(txt_fromtext(&token.value.as_textregion, target));
73
74         /*
75          * Regexp.
76          */
77         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
78                                       ISC_FALSE));
79         RETTOK(txt_fromtext(&token.value.as_textregion, target));
80
81         /*
82          * Replacement.
83          */
84         RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
85                                       ISC_FALSE));
86         dns_name_init(&name, NULL);
87         buffer_fromregion(&buffer, &token.value.as_region);
88         origin = (origin != NULL) ? origin : dns_rootname;
89         RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target));
90         return (ISC_R_SUCCESS);
91 }
92
93 static inline isc_result_t
94 totext_in_naptr(ARGS_TOTEXT) {
95         isc_region_t region;
96         dns_name_t name;
97         dns_name_t prefix;
98         isc_boolean_t sub;
99         char buf[sizeof("64000")];
100         unsigned short num;
101
102         REQUIRE(rdata->type == 35);
103         REQUIRE(rdata->rdclass == 1);
104         REQUIRE(rdata->length != 0);
105
106         dns_name_init(&name, NULL);
107         dns_name_init(&prefix, NULL);
108
109         dns_rdata_toregion(rdata, &region);
110
111         /*
112          * Order.
113          */
114         num = uint16_fromregion(&region);
115         isc_region_consume(&region, 2);
116         sprintf(buf, "%u", num);
117         RETERR(str_totext(buf, target));
118         RETERR(str_totext(" ", target));
119
120         /*
121          * Preference.
122          */
123         num = uint16_fromregion(&region);
124         isc_region_consume(&region, 2);
125         sprintf(buf, "%u", num);
126         RETERR(str_totext(buf, target));
127         RETERR(str_totext(" ", target));
128
129         /*
130          * Flags.
131          */
132         RETERR(txt_totext(&region, target));
133         RETERR(str_totext(" ", target));
134
135         /*
136          * Service.
137          */
138         RETERR(txt_totext(&region, target));
139         RETERR(str_totext(" ", target));
140
141         /*
142          * Regexp.
143          */
144         RETERR(txt_totext(&region, target));
145         RETERR(str_totext(" ", target));
146
147         /*
148          * Replacement.
149          */
150         dns_name_fromregion(&name, &region);
151         sub = name_prefix(&name, tctx->origin, &prefix);
152         return (dns_name_totext(&prefix, sub, target));
153 }
154
155 static inline isc_result_t
156 fromwire_in_naptr(ARGS_FROMWIRE) {
157         dns_name_t name;
158         isc_region_t sr;
159
160         REQUIRE(type == 35);
161         REQUIRE(rdclass == 1);
162
163         UNUSED(type);
164         UNUSED(rdclass);
165
166         dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
167
168         dns_name_init(&name, NULL);
169
170         /*
171          * Order, preference.
172          */
173         isc_buffer_activeregion(source, &sr);
174         if (sr.length < 4)
175                 return (ISC_R_UNEXPECTEDEND);
176         RETERR(mem_tobuffer(target, sr.base, 4));
177         isc_buffer_forward(source, 4);
178
179         /*
180          * Flags.
181          */
182         RETERR(txt_fromwire(source, target));
183
184         /*
185          * Service.
186          */
187         RETERR(txt_fromwire(source, target));
188
189         /*
190          * Regexp.
191          */
192         RETERR(txt_fromwire(source, target));
193
194         /*
195          * Replacement.
196          */
197         return (dns_name_fromwire(&name, source, dctx, options, target));
198 }
199
200 static inline isc_result_t
201 towire_in_naptr(ARGS_TOWIRE) {
202         dns_name_t name;
203         dns_offsets_t offsets;
204         isc_region_t sr;
205
206         REQUIRE(rdata->type == 35);
207         REQUIRE(rdata->rdclass == 1);
208         REQUIRE(rdata->length != 0);
209
210         dns_compress_setmethods(cctx, DNS_COMPRESS_NONE);
211         /*
212          * Order, preference.
213          */
214         dns_rdata_toregion(rdata, &sr);
215         RETERR(mem_tobuffer(target, sr.base, 4));
216         isc_region_consume(&sr, 4);
217
218         /*
219          * Flags.
220          */
221         RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
222         isc_region_consume(&sr, sr.base[0] + 1);
223
224         /*
225          * Service.
226          */
227         RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
228         isc_region_consume(&sr, sr.base[0] + 1);
229
230         /*
231          * Regexp.
232          */
233         RETERR(mem_tobuffer(target, sr.base, sr.base[0] + 1));
234         isc_region_consume(&sr, sr.base[0] + 1);
235
236         /*
237          * Replacement.
238          */
239         dns_name_init(&name, offsets);
240         dns_name_fromregion(&name, &sr);
241         return (dns_name_towire(&name, cctx, target));
242 }
243
244 static inline int
245 compare_in_naptr(ARGS_COMPARE) {
246         dns_name_t name1;
247         dns_name_t name2;
248         isc_region_t region1;
249         isc_region_t region2;
250         int order, len;
251
252         REQUIRE(rdata1->type == rdata2->type);
253         REQUIRE(rdata1->rdclass == rdata2->rdclass);
254         REQUIRE(rdata1->type == 35);
255         REQUIRE(rdata1->rdclass == 1);
256         REQUIRE(rdata1->length != 0);
257         REQUIRE(rdata2->length != 0);
258
259         dns_rdata_toregion(rdata1, &region1);
260         dns_rdata_toregion(rdata2, &region2);
261
262         /*
263          * Order, preference.
264          */
265         order = memcmp(region1.base, region2.base, 4);
266         if (order != 0)
267                 return (order < 0 ? -1 : 1);
268         isc_region_consume(&region1, 4);
269         isc_region_consume(&region2, 4);
270
271         /*
272          * Flags.
273          */
274         len = ISC_MIN(region1.base[0], region2.base[0]);
275         order = memcmp(region1.base, region2.base, len + 1);
276         if (order != 0)
277                 return (order < 0 ? -1 : 1);
278         isc_region_consume(&region1, region1.base[0] + 1);
279         isc_region_consume(&region2, region2.base[0] + 1);
280
281         /*
282          * Service.
283          */
284         len = ISC_MIN(region1.base[0], region2.base[0]);
285         order = memcmp(region1.base, region2.base, len + 1);
286         if (order != 0)
287                 return (order < 0 ? -1 : 1);
288         isc_region_consume(&region1, region1.base[0] + 1);
289         isc_region_consume(&region2, region2.base[0] + 1);
290
291         /*
292          * Regexp.
293          */
294         len = ISC_MIN(region1.base[0], region2.base[0]);
295         order = memcmp(region1.base, region2.base, len + 1);
296         if (order != 0)
297                 return (order < 0 ? -1 : 1);
298         isc_region_consume(&region1, region1.base[0] + 1);
299         isc_region_consume(&region2, region2.base[0] + 1);
300
301         /*
302          * Replacement.
303          */
304         dns_name_init(&name1, NULL);
305         dns_name_init(&name2, NULL);
306
307         dns_name_fromregion(&name1, &region1);
308         dns_name_fromregion(&name2, &region2);
309
310         return (dns_name_rdatacompare(&name1, &name2));
311 }
312
313 static inline isc_result_t
314 fromstruct_in_naptr(ARGS_FROMSTRUCT) {
315         dns_rdata_in_naptr_t *naptr = source;
316         isc_region_t region;
317
318         REQUIRE(type == 35);
319         REQUIRE(rdclass == 1);
320         REQUIRE(source != NULL);
321         REQUIRE(naptr->common.rdtype == type);
322         REQUIRE(naptr->common.rdclass == rdclass);
323         REQUIRE(naptr->flags != NULL || naptr->flags_len == 0);
324         REQUIRE(naptr->service != NULL && naptr->service_len == 0);
325         REQUIRE(naptr->regexp != NULL && naptr->regexp_len == 0);
326
327         UNUSED(type);
328         UNUSED(rdclass);
329
330         RETERR(uint16_tobuffer(naptr->order, target));
331         RETERR(uint16_tobuffer(naptr->preference, target));
332         RETERR(uint8_tobuffer(naptr->flags_len, target));
333         RETERR(mem_tobuffer(target, naptr->flags, naptr->flags_len));
334         RETERR(uint8_tobuffer(naptr->service_len, target));
335         RETERR(mem_tobuffer(target, naptr->service, naptr->service_len));
336         RETERR(uint8_tobuffer(naptr->regexp_len, target));
337         RETERR(mem_tobuffer(target, naptr->regexp, naptr->regexp_len));
338         dns_name_toregion(&naptr->replacement, &region);
339         return (isc_buffer_copyregion(target, &region));
340 }
341
342 static inline isc_result_t
343 tostruct_in_naptr(ARGS_TOSTRUCT) {
344         dns_rdata_in_naptr_t *naptr = target;
345         isc_region_t r;
346         isc_result_t result;
347         dns_name_t name;
348
349         REQUIRE(rdata->type == 35);
350         REQUIRE(rdata->rdclass == 1);
351         REQUIRE(target != NULL);
352         REQUIRE(rdata->length != 0);
353
354         naptr->common.rdclass = rdata->rdclass;
355         naptr->common.rdtype = rdata->type;
356         ISC_LINK_INIT(&naptr->common, link);
357
358         naptr->flags = NULL;
359         naptr->service = NULL;
360         naptr->regexp = NULL;
361
362         dns_rdata_toregion(rdata, &r);
363
364         naptr->order = uint16_fromregion(&r);
365         isc_region_consume(&r, 2);
366
367         naptr->preference = uint16_fromregion(&r);
368         isc_region_consume(&r, 2);
369
370         naptr->flags_len = uint8_fromregion(&r);
371         isc_region_consume(&r, 1);
372         INSIST(naptr->flags_len <= r.length);
373         naptr->flags = mem_maybedup(mctx, r.base, naptr->flags_len);
374         if (naptr->flags == NULL)
375                 goto cleanup;
376         isc_region_consume(&r, naptr->flags_len);
377
378         naptr->service_len = uint8_fromregion(&r);
379         isc_region_consume(&r, 1);
380         INSIST(naptr->service_len <= r.length);
381         naptr->service = mem_maybedup(mctx, r.base, naptr->service_len);
382         if (naptr->service == NULL)
383                 goto cleanup;
384         isc_region_consume(&r, naptr->service_len);
385
386         naptr->regexp_len = uint8_fromregion(&r);
387         isc_region_consume(&r, 1);
388         INSIST(naptr->regexp_len <= r.length);
389         naptr->regexp = mem_maybedup(mctx, r.base, naptr->regexp_len);
390         if (naptr->regexp == NULL)
391                 goto cleanup;
392         isc_region_consume(&r, naptr->regexp_len);
393
394         dns_name_init(&name, NULL);
395         dns_name_fromregion(&name, &r);
396         dns_name_init(&naptr->replacement, NULL);
397         result = name_duporclone(&name, mctx, &naptr->replacement);
398         if (result != ISC_R_SUCCESS)
399                 goto cleanup;
400         naptr->mctx = mctx;
401         return (ISC_R_SUCCESS);
402
403  cleanup:
404         if (mctx != NULL && naptr->flags != NULL)
405                 isc_mem_free(mctx, naptr->flags);
406         if (mctx != NULL && naptr->service != NULL)
407                 isc_mem_free(mctx, naptr->service);
408         if (mctx != NULL && naptr->regexp != NULL)
409                 isc_mem_free(mctx, naptr->regexp);
410         return (ISC_R_NOMEMORY);
411 }
412
413 static inline void
414 freestruct_in_naptr(ARGS_FREESTRUCT) {
415         dns_rdata_in_naptr_t *naptr = source;
416
417         REQUIRE(source != NULL);
418         REQUIRE(naptr->common.rdclass == 1);
419         REQUIRE(naptr->common.rdtype == 35);
420
421         if (naptr->mctx == NULL)
422                 return;
423
424         if (naptr->flags != NULL)
425                 isc_mem_free(naptr->mctx, naptr->flags);
426         if (naptr->service != NULL)
427                 isc_mem_free(naptr->mctx, naptr->service);
428         if (naptr->regexp != NULL)
429                 isc_mem_free(naptr->mctx, naptr->regexp);
430         dns_name_free(&naptr->replacement, naptr->mctx);
431         naptr->mctx = NULL;
432 }
433
434 static inline isc_result_t
435 additionaldata_in_naptr(ARGS_ADDLDATA) {
436         dns_name_t name;
437         dns_offsets_t offsets;
438         isc_region_t sr;
439         dns_rdatatype_t atype;
440         unsigned int i, flagslen;
441         char *cp;
442
443         REQUIRE(rdata->type == 35);
444         REQUIRE(rdata->rdclass == 1);
445
446         /*
447          * Order, preference.
448          */
449         dns_rdata_toregion(rdata, &sr);
450         isc_region_consume(&sr, 4);
451
452         /*
453          * Flags.
454          */
455         atype = 0;
456         flagslen = sr.base[0];
457         cp = (char *)&sr.base[1];
458         for (i = 0; i < flagslen; i++, cp++) {
459                 if (*cp == 'S' || *cp == 's') {
460                         atype = dns_rdatatype_srv;
461                         break;
462                 }
463                 if (*cp == 'A' || *cp == 'a') {
464                         atype = dns_rdatatype_a;
465                         break;
466                 }
467         }
468         isc_region_consume(&sr, flagslen + 1);
469
470         /*
471          * Service.
472          */
473         isc_region_consume(&sr, sr.base[0] + 1);
474
475         /*
476          * Regexp.
477          */
478         isc_region_consume(&sr, sr.base[0] + 1);
479
480         /*
481          * Replacement.
482          */
483         dns_name_init(&name, offsets);
484         dns_name_fromregion(&name, &sr);
485
486         if (atype != 0)
487                 return ((add)(arg, &name, atype));
488
489         return (ISC_R_SUCCESS);
490 }
491
492 static inline isc_result_t
493 digest_in_naptr(ARGS_DIGEST) {
494         isc_region_t r1, r2;
495         unsigned int length, n;
496         isc_result_t result;
497         dns_name_t name;
498
499         REQUIRE(rdata->type == 35);
500         REQUIRE(rdata->rdclass == 1);
501
502         dns_rdata_toregion(rdata, &r1);
503         r2 = r1;
504         length = 0;
505
506         /*
507          * Order, preference.
508          */
509         length += 4;
510         isc_region_consume(&r2, 4);
511
512         /*
513          * Flags.
514          */
515         n = r2.base[0] + 1;
516         length += n;
517         isc_region_consume(&r2, n);
518
519         /*
520          * Service.
521          */
522         n = r2.base[0] + 1;
523         length += n;
524         isc_region_consume(&r2, n);
525
526         /*
527          * Regexp.
528          */
529         n = r2.base[0] + 1;
530         length += n;
531         isc_region_consume(&r2, n);
532
533         /*
534          * Digest the RR up to the replacement name.
535          */
536         r1.length = length;
537         result = (digest)(arg, &r1);
538         if (result != ISC_R_SUCCESS)
539                 return (result);
540
541         /*
542          * Replacement.
543          */
544
545         dns_name_init(&name, NULL);
546         dns_name_fromregion(&name, &r2);
547
548         return (dns_name_digest(&name, digest, arg));
549 }
550
551 static inline isc_boolean_t
552 checkowner_in_naptr(ARGS_CHECKOWNER) {
553
554         REQUIRE(type == 35);
555         REQUIRE(rdclass == 1);
556
557         UNUSED(name);
558         UNUSED(type);
559         UNUSED(rdclass);
560         UNUSED(wildcard);
561
562         return (ISC_TRUE);
563 }
564
565 static inline isc_boolean_t
566 checknames_in_naptr(ARGS_CHECKNAMES) {
567
568         REQUIRE(rdata->type == 35);
569         REQUIRE(rdata->rdclass == 1);
570
571         UNUSED(rdata);
572         UNUSED(owner);
573         UNUSED(bad);
574
575         return (ISC_TRUE);
576 }
577
578 #endif  /* RDATA_IN_1_NAPTR_35_C */