2 * Copyright (C) 2009, 2011 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(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(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 size_t 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 hip->key = mem_maybedup(mctx, region.base, hip->key_len);
322 if (hip->key == NULL)
324 isc_region_consume(®ion, hip->key_len);
326 hip->servers_len = region.length;
327 if (hip->servers_len != 0) {
328 hip->servers = mem_maybedup(mctx, region.base, region.length);
329 if (hip->servers == NULL)
333 hip->offset = hip->servers_len;
335 return (ISC_R_SUCCESS);
338 if (hip->hit != NULL)
339 isc_mem_free(mctx, hip->hit);
340 if (hip->key != NULL)
341 isc_mem_free(mctx, hip->key);
342 if (hip->servers != NULL)
343 isc_mem_free(mctx, hip->servers);
344 return (ISC_R_NOMEMORY);
349 freestruct_hip(ARGS_FREESTRUCT) {
350 dns_rdata_hip_t *hip = source;
352 REQUIRE(source != NULL);
354 if (hip->mctx == NULL)
357 isc_mem_free(hip->mctx, hip->hit);
358 isc_mem_free(hip->mctx, hip->key);
359 if (hip->servers != NULL)
360 isc_mem_free(hip->mctx, hip->servers);
364 static inline isc_result_t
365 additionaldata_hip(ARGS_ADDLDATA) {
370 REQUIRE(rdata->type == 55);
372 return (ISC_R_SUCCESS);
375 static inline isc_result_t
376 digest_hip(ARGS_DIGEST) {
379 REQUIRE(rdata->type == 55);
381 dns_rdata_toregion(rdata, &r);
382 return ((digest)(arg, &r));
385 static inline isc_boolean_t
386 checkowner_hip(ARGS_CHECKOWNER) {
398 static inline isc_boolean_t
399 checknames_hip(ARGS_CHECKNAMES) {
401 REQUIRE(rdata->type == 55);
411 dns_rdata_hip_first(dns_rdata_hip_t *hip) {
412 if (hip->servers_len == 0)
413 return (ISC_R_NOMORE);
415 return (ISC_R_SUCCESS);
419 dns_rdata_hip_next(dns_rdata_hip_t *hip) {
423 if (hip->offset >= hip->servers_len)
424 return (ISC_R_NOMORE);
426 region.base = hip->servers + hip->offset;
427 region.length = hip->servers_len - hip->offset;
428 dns_name_init(&name, NULL);
429 dns_name_fromregion(&name, ®ion);
430 hip->offset += name.length;
431 INSIST(hip->offset <= hip->servers_len);
432 return (ISC_R_SUCCESS);
436 dns_rdata_hip_current(dns_rdata_hip_t *hip, dns_name_t *name) {
439 REQUIRE(hip->offset < hip->servers_len);
441 region.base = hip->servers + hip->offset;
442 region.length = hip->servers_len - hip->offset;
443 dns_name_fromregion(name, ®ion);
445 INSIST(name->length + hip->offset <= hip->servers_len);
449 casecompare_hip(ARGS_COMPARE) {
456 isc_uint16_t key_len;
458 REQUIRE(rdata1->type == rdata2->type);
459 REQUIRE(rdata1->rdclass == rdata2->rdclass);
460 REQUIRE(rdata1->type == 55);
461 REQUIRE(rdata1->length != 0);
462 REQUIRE(rdata2->length != 0);
464 dns_rdata_toregion(rdata1, &r1);
465 dns_rdata_toregion(rdata2, &r2);
467 INSIST(r1.length > 4);
468 INSIST(r2.length > 4);
471 order = isc_region_compare(&r1, &r2);
475 hit_len = uint8_fromregion(&r1);
476 isc_region_consume(&r1, 2); /* hit length + algorithm */
477 key_len = uint16_fromregion(&r1);
479 dns_rdata_toregion(rdata1, &r1);
480 dns_rdata_toregion(rdata2, &r2);
481 isc_region_consume(&r1, 4);
482 isc_region_consume(&r2, 4);
483 INSIST(r1.length >= (unsigned) (hit_len + key_len));
484 INSIST(r2.length >= (unsigned) (hit_len + key_len));
485 order = isc_region_compare(&r1, &r2);
488 isc_region_consume(&r1, hit_len + key_len);
489 isc_region_consume(&r2, hit_len + key_len);
491 dns_name_init(&name1, NULL);
492 dns_name_init(&name2, NULL);
493 while (r1.length != 0 && r2.length != 0) {
494 dns_name_fromregion(&name1, &r1);
495 dns_name_fromregion(&name2, &r2);
496 order = dns_name_rdatacompare(&name1, &name2);
500 isc_region_consume(&r1, name_length(&name1));
501 isc_region_consume(&r2, name_length(&name2));
503 return (isc_region_compare(&r1, &r2));
506 #endif /* RDATA_GENERIC_HIP_5_C */