1 /*
2 * Copyright (C) 2004, 2007-2009, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1998-2002 Internet Software Consortium.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 /* Reviewed: Thu Mar 16 15:40:00 PST 2000 by bwelling */
19
20 #ifndef RDATA_GENERIC_TXT_16_C
21 #define RDATA_GENERIC_TXT_16_C
22
23 #define RRTYPE_TXT_ATTRIBUTES (0)
24
25 static inline isc_result_t
generic_fromtext_txt(ARGS_FROMTEXT)26 generic_fromtext_txt(ARGS_FROMTEXT) {
27 isc_token_t token;
28 int strings;
29
30 UNUSED(type);
31 UNUSED(rdclass);
32 UNUSED(origin);
33 UNUSED(options);
34 UNUSED(callbacks);
35
36 strings = 0;
37 if ((options & DNS_RDATA_UNKNOWNESCAPE) != 0) {
38 isc_textregion_t r;
39 DE_CONST("#", r.base);
40 r.length = 1;
41 RETERR(txt_fromtext(&r, target));
42 strings++;
43 }
44 for (;;) {
45 RETERR(isc_lex_getmastertoken(lexer, &token,
46 isc_tokentype_qstring,
47 ISC_TRUE));
48 if (token.type != isc_tokentype_qstring &&
49 token.type != isc_tokentype_string)
50 break;
51 RETTOK(txt_fromtext(&token.value.as_textregion, target));
52 strings++;
53 }
54 /* Let upper layer handle eol/eof. */
55 isc_lex_ungettoken(lexer, &token);
56 return (strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS);
57 }
58
59 static inline isc_result_t
generic_totext_txt(ARGS_TOTEXT)60 generic_totext_txt(ARGS_TOTEXT) {
61 isc_region_t region;
62
63 UNUSED(tctx);
64
65 dns_rdata_toregion(rdata, ®ion);
66
67 while (region.length > 0) {
68 RETERR(txt_totext(®ion, ISC_TRUE, target));
69 if (region.length > 0)
70 RETERR(str_totext(" ", target));
71 }
72
73 return (ISC_R_SUCCESS);
74 }
75
76 static inline isc_result_t
generic_fromwire_txt(ARGS_FROMWIRE)77 generic_fromwire_txt(ARGS_FROMWIRE) {
78 isc_result_t result;
79
80 UNUSED(type);
81 UNUSED(dctx);
82 UNUSED(rdclass);
83 UNUSED(options);
84
85 do {
86 result = txt_fromwire(source, target);
87 if (result != ISC_R_SUCCESS)
88 return (result);
89 } while (!buffer_empty(source));
90 return (ISC_R_SUCCESS);
91 }
92
93 static inline isc_result_t
fromtext_txt(ARGS_FROMTEXT)94 fromtext_txt(ARGS_FROMTEXT) {
95
96 REQUIRE(type == dns_rdatatype_txt);
97
98 return (generic_fromtext_txt(rdclass, type, lexer, origin, options,
99 target, callbacks));
100 }
101
102 static inline isc_result_t
totext_txt(ARGS_TOTEXT)103 totext_txt(ARGS_TOTEXT) {
104
105 REQUIRE(rdata->type == dns_rdatatype_txt);
106
107 return (generic_totext_txt(rdata, tctx, target));
108 }
109
110 static inline isc_result_t
fromwire_txt(ARGS_FROMWIRE)111 fromwire_txt(ARGS_FROMWIRE) {
112
113 REQUIRE(type == dns_rdatatype_txt);
114
115 return (generic_fromwire_txt(rdclass, type, source, dctx, options,
116 target));
117 }
118
119 static inline isc_result_t
towire_txt(ARGS_TOWIRE)120 towire_txt(ARGS_TOWIRE) {
121
122 REQUIRE(rdata->type == dns_rdatatype_txt);
123
124 UNUSED(cctx);
125
126 return (mem_tobuffer(target, rdata->data, rdata->length));
127 }
128
129 static inline int
compare_txt(ARGS_COMPARE)130 compare_txt(ARGS_COMPARE) {
131 isc_region_t r1;
132 isc_region_t r2;
133
134 REQUIRE(rdata1->type == rdata2->type);
135 REQUIRE(rdata1->rdclass == rdata2->rdclass);
136 REQUIRE(rdata1->type == dns_rdatatype_txt);
137
138 dns_rdata_toregion(rdata1, &r1);
139 dns_rdata_toregion(rdata2, &r2);
140 return (isc_region_compare(&r1, &r2));
141 }
142
143 static inline isc_result_t
generic_fromstruct_txt(ARGS_FROMSTRUCT)144 generic_fromstruct_txt(ARGS_FROMSTRUCT) {
145 dns_rdata_txt_t *txt = source;
146 isc_region_t region;
147 isc_uint8_t length;
148
149 REQUIRE(source != NULL);
150 REQUIRE(txt->common.rdtype == type);
151 REQUIRE(txt->common.rdclass == rdclass);
152 REQUIRE(txt->txt != NULL && txt->txt_len != 0);
153
154 UNUSED(type);
155 UNUSED(rdclass);
156
157 region.base = txt->txt;
158 region.length = txt->txt_len;
159 while (region.length > 0) {
160 length = uint8_fromregion(®ion);
161 isc_region_consume(®ion, 1);
162 if (region.length < length)
163 return (ISC_R_UNEXPECTEDEND);
164 isc_region_consume(®ion, length);
165 }
166
167 return (mem_tobuffer(target, txt->txt, txt->txt_len));
168 }
169
170 static inline isc_result_t
generic_tostruct_txt(ARGS_TOSTRUCT)171 generic_tostruct_txt(ARGS_TOSTRUCT) {
172 dns_rdata_txt_t *txt = target;
173 isc_region_t r;
174
175 REQUIRE(target != NULL);
176 REQUIRE(txt->common.rdclass == rdata->rdclass);
177 REQUIRE(txt->common.rdtype == rdata->type);
178 REQUIRE(!ISC_LINK_LINKED(&txt->common, link));
179
180 dns_rdata_toregion(rdata, &r);
181 txt->txt_len = r.length;
182 txt->txt = mem_maybedup(mctx, r.base, r.length);
183 if (txt->txt == NULL)
184 return (ISC_R_NOMEMORY);
185
186 txt->offset = 0;
187 txt->mctx = mctx;
188 return (ISC_R_SUCCESS);
189 }
190
191 static inline void
generic_freestruct_txt(ARGS_FREESTRUCT)192 generic_freestruct_txt(ARGS_FREESTRUCT) {
193 dns_rdata_txt_t *txt = source;
194
195 REQUIRE(source != NULL);
196
197 if (txt->mctx == NULL)
198 return;
199
200 if (txt->txt != NULL)
201 isc_mem_free(txt->mctx, txt->txt);
202 txt->mctx = NULL;
203 }
204
205 static inline isc_result_t
fromstruct_txt(ARGS_FROMSTRUCT)206 fromstruct_txt(ARGS_FROMSTRUCT) {
207
208 REQUIRE(type == dns_rdatatype_txt);
209
210 return (generic_fromstruct_txt(rdclass, type, source, target));
211 }
212
213 static inline isc_result_t
tostruct_txt(ARGS_TOSTRUCT)214 tostruct_txt(ARGS_TOSTRUCT) {
215 dns_rdata_txt_t *txt = target;
216
217 REQUIRE(rdata->type == dns_rdatatype_txt);
218 REQUIRE(target != NULL);
219
220 txt->common.rdclass = rdata->rdclass;
221 txt->common.rdtype = rdata->type;
222 ISC_LINK_INIT(&txt->common, link);
223
224 return (generic_tostruct_txt(rdata, target, mctx));
225 }
226
227 static inline void
freestruct_txt(ARGS_FREESTRUCT)228 freestruct_txt(ARGS_FREESTRUCT) {
229 dns_rdata_txt_t *txt = source;
230
231 REQUIRE(source != NULL);
232 REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
233
234 generic_freestruct_txt(source);
235 }
236
237 static inline isc_result_t
additionaldata_txt(ARGS_ADDLDATA)238 additionaldata_txt(ARGS_ADDLDATA) {
239 REQUIRE(rdata->type == dns_rdatatype_txt);
240
241 UNUSED(rdata);
242 UNUSED(add);
243 UNUSED(arg);
244
245 return (ISC_R_SUCCESS);
246 }
247
248 static inline isc_result_t
digest_txt(ARGS_DIGEST)249 digest_txt(ARGS_DIGEST) {
250 isc_region_t r;
251
252 REQUIRE(rdata->type == dns_rdatatype_txt);
253
254 dns_rdata_toregion(rdata, &r);
255
256 return ((digest)(arg, &r));
257 }
258
259 static inline isc_boolean_t
checkowner_txt(ARGS_CHECKOWNER)260 checkowner_txt(ARGS_CHECKOWNER) {
261
262 REQUIRE(type == dns_rdatatype_txt);
263
264 UNUSED(name);
265 UNUSED(type);
266 UNUSED(rdclass);
267 UNUSED(wildcard);
268
269 return (ISC_TRUE);
270 }
271
272 static inline isc_boolean_t
checknames_txt(ARGS_CHECKNAMES)273 checknames_txt(ARGS_CHECKNAMES) {
274
275 REQUIRE(rdata->type == dns_rdatatype_txt);
276
277 UNUSED(rdata);
278 UNUSED(owner);
279 UNUSED(bad);
280
281 return (ISC_TRUE);
282 }
283
284 static inline isc_result_t
casecompare_txt(ARGS_COMPARE)285 casecompare_txt(ARGS_COMPARE) {
286 return (compare_txt(rdata1, rdata2));
287 }
288
289 static isc_result_t
generic_txt_first(dns_rdata_txt_t * txt)290 generic_txt_first(dns_rdata_txt_t *txt) {
291
292 REQUIRE(txt != NULL);
293 REQUIRE(txt->txt != NULL || txt->txt_len == 0);
294
295 if (txt->txt_len == 0)
296 return (ISC_R_NOMORE);
297
298 txt->offset = 0;
299 return (ISC_R_SUCCESS);
300 }
301
302 static isc_result_t
generic_txt_next(dns_rdata_txt_t * txt)303 generic_txt_next(dns_rdata_txt_t *txt) {
304 isc_region_t r;
305 isc_uint8_t length;
306
307 REQUIRE(txt != NULL);
308 REQUIRE(txt->txt != NULL && txt->txt_len != 0);
309
310 INSIST(txt->offset + 1 <= txt->txt_len);
311 r.base = txt->txt + txt->offset;
312 r.length = txt->txt_len - txt->offset;
313 length = uint8_fromregion(&r);
314 INSIST(txt->offset + 1 + length <= txt->txt_len);
315 txt->offset = txt->offset + 1 + length;
316 if (txt->offset == txt->txt_len)
317 return (ISC_R_NOMORE);
318 return (ISC_R_SUCCESS);
319 }
320
321 static isc_result_t
generic_txt_current(dns_rdata_txt_t * txt,dns_rdata_txt_string_t * string)322 generic_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) {
323 isc_region_t r;
324
325 REQUIRE(txt != NULL);
326 REQUIRE(string != NULL);
327 REQUIRE(txt->txt != NULL);
328 REQUIRE(txt->offset < txt->txt_len);
329
330 INSIST(txt->offset + 1 <= txt->txt_len);
331 r.base = txt->txt + txt->offset;
332 r.length = txt->txt_len - txt->offset;
333
334 string->length = uint8_fromregion(&r);
335 isc_region_consume(&r, 1);
336 string->data = r.base;
337 INSIST(txt->offset + 1 + string->length <= txt->txt_len);
338
339 return (ISC_R_SUCCESS);
340 }
341
342 isc_result_t
dns_rdata_txt_first(dns_rdata_txt_t * txt)343 dns_rdata_txt_first(dns_rdata_txt_t *txt) {
344
345 REQUIRE(txt != NULL);
346 REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
347
348 return (generic_txt_first(txt));
349 }
350
351 isc_result_t
dns_rdata_txt_next(dns_rdata_txt_t * txt)352 dns_rdata_txt_next(dns_rdata_txt_t *txt) {
353
354 REQUIRE(txt != NULL);
355 REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
356
357 return (generic_txt_next(txt));
358 }
359
360 isc_result_t
dns_rdata_txt_current(dns_rdata_txt_t * txt,dns_rdata_txt_string_t * string)361 dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) {
362
363 REQUIRE(txt != NULL);
364 REQUIRE(txt->common.rdtype == dns_rdatatype_txt);
365
366 return (generic_txt_current(txt, string));
367 }
368 #endif /* RDATA_GENERIC_TXT_16_C */
369