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: apl_42.c,v 1.14 2020/09/14 08:40:44 florian Exp $ */
18
19 /* RFC3123 */
20
21 #ifndef RDATA_IN_1_APL_42_C
22 #define RDATA_IN_1_APL_42_C
23
24 static inline isc_result_t
totext_in_apl(ARGS_TOTEXT)25 totext_in_apl(ARGS_TOTEXT) {
26 isc_region_t sr;
27 isc_region_t ir;
28 uint16_t afi;
29 uint8_t prefix;
30 uint8_t len;
31 int neg;
32 unsigned char buf[16];
33 char txt[sizeof(" !64000:")];
34 const char *sep = "";
35 int n;
36
37 REQUIRE(rdata->type == dns_rdatatype_apl);
38 REQUIRE(rdata->rdclass == dns_rdataclass_in);
39
40 UNUSED(tctx);
41
42 dns_rdata_toregion(rdata, &sr);
43 ir.base = buf;
44 ir.length = sizeof(buf);
45
46 while (sr.length > 0) {
47 INSIST(sr.length >= 4);
48 afi = uint16_fromregion(&sr);
49 isc_region_consume(&sr, 2);
50 prefix = *sr.base;
51 isc_region_consume(&sr, 1);
52 len = (*sr.base & 0x7f);
53 neg = (*sr.base & 0x80) != 0;
54 isc_region_consume(&sr, 1);
55 INSIST(len <= sr.length);
56 n = snprintf(txt, sizeof(txt), "%s%s%u:", sep,
57 neg ? "!" : "", afi);
58 INSIST(n < (int)sizeof(txt));
59 RETERR(isc_str_tobuffer(txt, target));
60 switch (afi) {
61 case 1:
62 INSIST(len <= 4);
63 INSIST(prefix <= 32);
64 memset(buf, 0, sizeof(buf));
65 memmove(buf, sr.base, len);
66 RETERR(inet_totext(AF_INET, &ir, target));
67 break;
68
69 case 2:
70 INSIST(len <= 16);
71 INSIST(prefix <= 128);
72 memset(buf, 0, sizeof(buf));
73 memmove(buf, sr.base, len);
74 RETERR(inet_totext(AF_INET6, &ir, target));
75 break;
76
77 default:
78 return (ISC_R_NOTIMPLEMENTED);
79 }
80 n = snprintf(txt, sizeof(txt), "/%u", prefix);
81 INSIST(n < (int)sizeof(txt));
82 RETERR(isc_str_tobuffer(txt, target));
83 isc_region_consume(&sr, len);
84 sep = " ";
85 }
86 return (ISC_R_SUCCESS);
87 }
88
89 static inline isc_result_t
fromwire_in_apl(ARGS_FROMWIRE)90 fromwire_in_apl(ARGS_FROMWIRE) {
91 isc_region_t sr, sr2;
92 isc_region_t tr;
93 uint16_t afi;
94 uint8_t prefix;
95 uint8_t len;
96
97 REQUIRE(type == dns_rdatatype_apl);
98 REQUIRE(rdclass == dns_rdataclass_in);
99
100 UNUSED(type);
101 UNUSED(dctx);
102 UNUSED(rdclass);
103 UNUSED(options);
104
105 isc_buffer_activeregion(source, &sr);
106 isc_buffer_availableregion(target, &tr);
107 if (sr.length > tr.length)
108 return (ISC_R_NOSPACE);
109 sr2 = sr;
110
111 /* Zero or more items */
112 while (sr.length > 0) {
113 if (sr.length < 4)
114 return (ISC_R_UNEXPECTEDEND);
115 afi = uint16_fromregion(&sr);
116 isc_region_consume(&sr, 2);
117 prefix = *sr.base;
118 isc_region_consume(&sr, 1);
119 len = (*sr.base & 0x7f);
120 isc_region_consume(&sr, 1);
121 if (len > sr.length)
122 return (ISC_R_UNEXPECTEDEND);
123 switch (afi) {
124 case 1:
125 if (prefix > 32 || len > 4)
126 return (ISC_R_RANGE);
127 break;
128 case 2:
129 if (prefix > 128 || len > 16)
130 return (ISC_R_RANGE);
131 }
132 if (len > 0 && sr.base[len - 1] == 0)
133 return (DNS_R_FORMERR);
134 isc_region_consume(&sr, len);
135 }
136 isc_buffer_forward(source, sr2.length);
137 return (isc_mem_tobuffer(target, sr2.base, sr2.length));
138 }
139
140 static inline isc_result_t
towire_in_apl(ARGS_TOWIRE)141 towire_in_apl(ARGS_TOWIRE) {
142 UNUSED(cctx);
143
144 REQUIRE(rdata->type == dns_rdatatype_apl);
145 REQUIRE(rdata->rdclass == dns_rdataclass_in);
146
147 return (isc_mem_tobuffer(target, rdata->data, rdata->length));
148 }
149
150 #endif /* RDATA_IN_1_APL_42_C */
151