2 * Copyright (C) 2009, 2011, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
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.
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.
17 /* $Id: hip_55.c,v 1.8 2011/01/13 04:59:26 tbox Exp $ */
23 #ifndef RDATA_GENERIC_HIP_5_C
24 #define RDATA_GENERIC_HIP_5_C
26 #define RRTYPE_HIP_ATTRIBUTES (0)
28 static inline isc_result_t
29 fromtext_hip(ARGS_FROMTEXT) {
48 RETERR(uint8_tobuffer(0, target));
53 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
55 if (token.value.as_ulong > 0xffU)
57 RETERR(uint8_tobuffer(token.value.as_ulong, target));
63 RETERR(uint16_tobuffer(0, target));
68 start = isc_buffer_used(target);
69 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
71 RETTOK(isc_hex_decodestring(DNS_AS_STR(token), target));
76 len = (unsigned char *)isc_buffer_used(target) - start;
79 RETERR(uint8_tobuffer((isc_uint32_t)len, &hit_len));
82 * Public key (base64).
84 start = isc_buffer_used(target);
85 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
87 RETTOK(isc_base64_decodestring(DNS_AS_STR(token), target));
92 len = (unsigned char *)isc_buffer_used(target) - start;
95 RETERR(uint16_tobuffer((isc_uint32_t)len, &key_len));
100 dns_name_init(&name, NULL);
102 RETERR(isc_lex_getmastertoken(lexer, &token,
103 isc_tokentype_string,
105 if (token.type != isc_tokentype_string)
107 buffer_fromregion(&buffer, &token.value.as_region);
108 origin = (origin != NULL) ? origin : dns_rootname;
109 RETTOK(dns_name_fromtext(&name, &buffer, origin, options,
114 * Let upper layer handle eol/eof.
116 isc_lex_ungettoken(lexer, &token);
118 return (ISC_R_SUCCESS);
121 static inline isc_result_t
122 totext_hip(ARGS_TOTEXT) {
125 unsigned int length, key_len, hit_len;
126 unsigned char algorithm;
127 char buf[sizeof("225 ")];
129 REQUIRE(rdata->type == 55);
130 REQUIRE(rdata->length != 0);
132 dns_rdata_toregion(rdata, ®ion);
134 hit_len = uint8_fromregion(®ion);
135 isc_region_consume(®ion, 1);
137 algorithm = uint8_fromregion(®ion);
138 isc_region_consume(®ion, 1);
140 key_len = uint16_fromregion(®ion);
141 isc_region_consume(®ion, 2);
143 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
144 RETERR(str_totext("( ", target));
149 sprintf(buf, "%u ", algorithm);
150 RETERR(str_totext(buf, target));
155 INSIST(hit_len < region.length);
156 length = region.length;
157 region.length = hit_len;
158 RETERR(isc_hex_totext(®ion, 1, "", target));
159 region.length = length - hit_len;
160 RETERR(str_totext(tctx->linebreak, target));
165 INSIST(key_len <= region.length);
166 length = region.length;
167 region.length = key_len;
168 RETERR(isc_base64_totext(®ion, 1, "", target));
169 region.length = length - key_len;
170 RETERR(str_totext(tctx->linebreak, target));
173 * Rendezvous Servers.
175 dns_name_init(&name, NULL);
176 while (region.length > 0) {
177 dns_name_fromregion(&name, ®ion);
179 RETERR(dns_name_totext(&name, ISC_FALSE, target));
180 isc_region_consume(®ion, name.length);
181 if (region.length > 0)
182 RETERR(str_totext(tctx->linebreak, target));
184 if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
185 RETERR(str_totext(" )", target));
186 return (ISC_R_SUCCESS);
189 static inline isc_result_t
190 fromwire_hip(ARGS_FROMWIRE) {
191 isc_region_t region, rr;
194 isc_uint16_t key_len;
201 isc_buffer_activeregion(source, ®ion);
202 if (region.length < 4U)
203 RETERR(DNS_R_FORMERR);
206 hit_len = uint8_fromregion(®ion);
208 RETERR(DNS_R_FORMERR);
209 isc_region_consume(®ion, 2); /* hit length + algorithm */
210 key_len = uint16_fromregion(®ion);
212 RETERR(DNS_R_FORMERR);
213 isc_region_consume(®ion, 2);
214 if (region.length < (unsigned) (hit_len + key_len))
215 RETERR(DNS_R_FORMERR);
217 RETERR(mem_tobuffer(target, rr.base, 4 + hit_len + key_len));
218 isc_buffer_forward(source, 4 + hit_len + key_len);
220 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE);
221 while (isc_buffer_activelength(source) > 0) {
222 dns_name_init(&name, NULL);
223 RETERR(dns_name_fromwire(&name, source, dctx, options, target));
225 return (ISC_R_SUCCESS);
228 static inline isc_result_t
229 towire_hip(ARGS_TOWIRE) {
232 REQUIRE(rdata->type == 55);
233 REQUIRE(rdata->length != 0);
237 dns_rdata_toregion(rdata, ®ion);
238 return (mem_tobuffer(target, region.base, region.length));
242 compare_hip(ARGS_COMPARE) {
243 isc_region_t region1;
244 isc_region_t region2;
246 REQUIRE(rdata1->type == rdata2->type);
247 REQUIRE(rdata1->rdclass == rdata2->rdclass);
248 REQUIRE(rdata1->type == 55);
249 REQUIRE(rdata1->length != 0);
250 REQUIRE(rdata2->length != 0);
252 dns_rdata_toregion(rdata1, ®ion1);
253 dns_rdata_toregion(rdata2, ®ion2);
254 return (isc_region_compare(®ion1, ®ion2));
257 static inline isc_result_t
258 fromstruct_hip(ARGS_FROMSTRUCT) {
259 dns_rdata_hip_t *hip = source;
260 dns_rdata_hip_t myhip;
264 REQUIRE(source != NULL);
265 REQUIRE(hip->common.rdtype == type);
266 REQUIRE(hip->common.rdclass == rdclass);
267 REQUIRE(hip->hit_len > 0 && hip->hit != NULL);
268 REQUIRE(hip->key_len > 0 && hip->key != NULL);
269 REQUIRE((hip->servers == NULL && hip->servers_len == 0) ||
270 (hip->servers != NULL && hip->servers_len != 0));
275 RETERR(uint8_tobuffer(hip->hit_len, target));
276 RETERR(uint8_tobuffer(hip->algorithm, target));
277 RETERR(uint16_tobuffer(hip->key_len, target));
278 RETERR(mem_tobuffer(target, hip->hit, hip->hit_len));
279 RETERR(mem_tobuffer(target, hip->key, hip->key_len));
282 for (result = dns_rdata_hip_first(&myhip);
283 result == ISC_R_SUCCESS;
284 result = dns_rdata_hip_next(&myhip))
287 return(mem_tobuffer(target, hip->servers, hip->servers_len));
290 static inline isc_result_t
291 tostruct_hip(ARGS_TOSTRUCT) {
293 dns_rdata_hip_t *hip = target;
295 REQUIRE(rdata->type == 55);
296 REQUIRE(target != NULL);
297 REQUIRE(rdata->length != 0);
299 hip->common.rdclass = rdata->rdclass;
300 hip->common.rdtype = rdata->type;
301 ISC_LINK_INIT(&hip->common, link);
303 dns_rdata_toregion(rdata, ®ion);
305 hip->hit_len = uint8_fromregion(®ion);
306 isc_region_consume(®ion, 1);
308 hip->algorithm = uint8_fromregion(®ion);
309 isc_region_consume(®ion, 1);
311 hip->key_len = uint16_fromregion(®ion);
312 isc_region_consume(®ion, 2);
314 hip->hit = hip->key = hip->servers = NULL;
316 hip->hit = mem_maybedup(mctx, region.base, hip->hit_len);
317 if (hip->hit == NULL)
319 isc_region_consume(®ion, hip->hit_len);
321 INSIST(hip->key_len <= region.length);
323 hip->key = mem_maybedup(mctx, region.base, hip->key_len);
324 if (hip->key == NULL)
326 isc_region_consume(®ion, hip->key_len);
328 hip->servers_len = region.length;
329 if (hip->servers_len != 0) {
330 hip->servers = mem_maybedup(mctx, region.base, region.length);
331 if (hip->servers == NULL)
335 hip->offset = hip->servers_len;
337 return (ISC_R_SUCCESS);
340 if (hip->hit != NULL)
341 isc_mem_free(mctx, hip->hit);
342 if (hip->key != NULL)
343 isc_mem_free(mctx, hip->key);
344 if (hip->servers != NULL)
345 isc_mem_free(mctx, hip->servers);
346 return (ISC_R_NOMEMORY);
351 freestruct_hip(ARGS_FREESTRUCT) {
352 dns_rdata_hip_t *hip = source;
354 REQUIRE(source != NULL);
356 if (hip->mctx == NULL)
359 isc_mem_free(hip->mctx, hip->hit);
360 isc_mem_free(hip->mctx, hip->key);
361 if (hip->servers != NULL)
362 isc_mem_free(hip->mctx, hip->servers);
366 static inline isc_result_t
367 additionaldata_hip(ARGS_ADDLDATA) {
372 REQUIRE(rdata->type == 55);
374 return (ISC_R_SUCCESS);
377 static inline isc_result_t
378 digest_hip(ARGS_DIGEST) {
381 REQUIRE(rdata->type == 55);
383 dns_rdata_toregion(rdata, &r);
384 return ((digest)(arg, &r));
387 static inline isc_boolean_t
388 checkowner_hip(ARGS_CHECKOWNER) {
400 static inline isc_boolean_t
401 checknames_hip(ARGS_CHECKNAMES) {
403 REQUIRE(rdata->type == 55);
413 dns_rdata_hip_first(dns_rdata_hip_t *hip) {
414 if (hip->servers_len == 0)
415 return (ISC_R_NOMORE);
417 return (ISC_R_SUCCESS);
421 dns_rdata_hip_next(dns_rdata_hip_t *hip) {
425 if (hip->offset >= hip->servers_len)
426 return (ISC_R_NOMORE);
428 region.base = hip->servers + hip->offset;
429 region.length = hip->servers_len - hip->offset;
430 dns_name_init(&name, NULL);
431 dns_name_fromregion(&name, ®ion);
432 hip->offset += name.length;
433 INSIST(hip->offset <= hip->servers_len);
434 return (ISC_R_SUCCESS);
438 dns_rdata_hip_current(dns_rdata_hip_t *hip, dns_name_t *name) {
441 REQUIRE(hip->offset < hip->servers_len);
443 region.base = hip->servers + hip->offset;
444 region.length = hip->servers_len - hip->offset;
445 dns_name_fromregion(name, ®ion);
447 INSIST(name->length + hip->offset <= hip->servers_len);
451 casecompare_hip(ARGS_COMPARE) {
458 isc_uint16_t key_len;
460 REQUIRE(rdata1->type == rdata2->type);
461 REQUIRE(rdata1->rdclass == rdata2->rdclass);
462 REQUIRE(rdata1->type == 55);
463 REQUIRE(rdata1->length != 0);
464 REQUIRE(rdata2->length != 0);
466 dns_rdata_toregion(rdata1, &r1);
467 dns_rdata_toregion(rdata2, &r2);
469 INSIST(r1.length > 4);
470 INSIST(r2.length > 4);
471 order = memcmp(r1.base, r2.base, 4);
475 hit_len = uint8_fromregion(&r1);
476 isc_region_consume(&r1, 2); /* hit length + algorithm */
477 key_len = uint16_fromregion(&r1);
478 isc_region_consume(&r1, 2); /* key length */
479 isc_region_consume(&r2, 4);
481 INSIST(r1.length >= (unsigned) (hit_len + key_len));
482 INSIST(r2.length >= (unsigned) (hit_len + key_len));
483 order = memcmp(r1.base, r2.base, hit_len + key_len);
486 isc_region_consume(&r1, hit_len + key_len);
487 isc_region_consume(&r2, hit_len + key_len);
489 dns_name_init(&name1, NULL);
490 dns_name_init(&name2, NULL);
491 while (r1.length != 0 && r2.length != 0) {
492 dns_name_fromregion(&name1, &r1);
493 dns_name_fromregion(&name2, &r2);
494 order = dns_name_rdatacompare(&name1, &name2);
498 isc_region_consume(&r1, name_length(&name1));
499 isc_region_consume(&r2, name_length(&name2));
501 return (isc_region_compare(&r1, &r2));
504 #endif /* RDATA_GENERIC_HIP_5_C */