1/* $NetBSD: srv_33.c,v 1.2.6.1 2012/06/05 21:15:05 bouyer Exp $ */ 2 3/* 4 * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") 5 * Copyright (C) 1999-2001, 2003 Internet Software Consortium. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20/* Id: srv_33.c,v 1.47 2009/12/04 22:06:37 tbox Exp */ 21 22/* Reviewed: Fri Mar 17 13:01:00 PST 2000 by bwelling */ 23 24/* RFC2782 */ 25 26#ifndef RDATA_IN_1_SRV_33_C 27#define RDATA_IN_1_SRV_33_C 28 29#define RRTYPE_SRV_ATTRIBUTES (0) 30 31static inline isc_result_t 32fromtext_in_srv(ARGS_FROMTEXT) { 33 isc_token_t token; 34 dns_name_t name; 35 isc_buffer_t buffer; 36 isc_boolean_t ok; 37 38 REQUIRE(type == 33); 39 REQUIRE(rdclass == 1); 40 41 UNUSED(type); 42 UNUSED(rdclass); 43 UNUSED(callbacks); 44 45 /* 46 * Priority. 47 */ 48 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 49 ISC_FALSE)); 50 if (token.value.as_ulong > 0xffffU) 51 RETTOK(ISC_R_RANGE); 52 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 53 54 /* 55 * Weight. 56 */ 57 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 58 ISC_FALSE)); 59 if (token.value.as_ulong > 0xffffU) 60 RETTOK(ISC_R_RANGE); 61 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 62 63 /* 64 * Port. 65 */ 66 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 67 ISC_FALSE)); 68 if (token.value.as_ulong > 0xffffU) 69 RETTOK(ISC_R_RANGE); 70 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 71 72 /* 73 * Target. 74 */ 75 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 76 ISC_FALSE)); 77 dns_name_init(&name, NULL); 78 buffer_fromregion(&buffer, &token.value.as_region); 79 origin = (origin != NULL) ? origin : dns_rootname; 80 RETTOK(dns_name_fromtext(&name, &buffer, origin, options, target)); 81 ok = ISC_TRUE; 82 if ((options & DNS_RDATA_CHECKNAMES) != 0) 83 ok = dns_name_ishostname(&name, ISC_FALSE); 84 if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0) 85 RETTOK(DNS_R_BADNAME); 86 if (!ok && callbacks != NULL) 87 warn_badname(&name, lexer, callbacks); 88 return (ISC_R_SUCCESS); 89} 90 91static inline isc_result_t 92totext_in_srv(ARGS_TOTEXT) { 93 isc_region_t region; 94 dns_name_t name; 95 dns_name_t prefix; 96 isc_boolean_t sub; 97 char buf[sizeof("64000")]; 98 unsigned short num; 99 100 REQUIRE(rdata->type == 33); 101 REQUIRE(rdata->rdclass == 1); 102 REQUIRE(rdata->length != 0); 103 104 dns_name_init(&name, NULL); 105 dns_name_init(&prefix, NULL); 106 107 /* 108 * Priority. 109 */ 110 dns_rdata_toregion(rdata, ®ion); 111 num = uint16_fromregion(®ion); 112 isc_region_consume(®ion, 2); 113 sprintf(buf, "%u", num); 114 RETERR(str_totext(buf, target)); 115 RETERR(str_totext(" ", target)); 116 117 /* 118 * Weight. 119 */ 120 num = uint16_fromregion(®ion); 121 isc_region_consume(®ion, 2); 122 sprintf(buf, "%u", num); 123 RETERR(str_totext(buf, target)); 124 RETERR(str_totext(" ", target)); 125 126 /* 127 * Port. 128 */ 129 num = uint16_fromregion(®ion); 130 isc_region_consume(®ion, 2); 131 sprintf(buf, "%u", num); 132 RETERR(str_totext(buf, target)); 133 RETERR(str_totext(" ", target)); 134 135 /* 136 * Target. 137 */ 138 dns_name_fromregion(&name, ®ion); 139 sub = name_prefix(&name, tctx->origin, &prefix); 140 return (dns_name_totext(&prefix, sub, target)); 141} 142 143static inline isc_result_t 144fromwire_in_srv(ARGS_FROMWIRE) { 145 dns_name_t name; 146 isc_region_t sr; 147 148 REQUIRE(type == 33); 149 REQUIRE(rdclass == 1); 150 151 UNUSED(type); 152 UNUSED(rdclass); 153 154 dns_decompress_setmethods(dctx, DNS_COMPRESS_NONE); 155 156 dns_name_init(&name, NULL); 157 158 /* 159 * Priority, weight, port. 160 */ 161 isc_buffer_activeregion(source, &sr); 162 if (sr.length < 6) 163 return (ISC_R_UNEXPECTEDEND); 164 RETERR(mem_tobuffer(target, sr.base, 6)); 165 isc_buffer_forward(source, 6); 166 167 /* 168 * Target. 169 */ 170 return (dns_name_fromwire(&name, source, dctx, options, target)); 171} 172 173static inline isc_result_t 174towire_in_srv(ARGS_TOWIRE) { 175 dns_name_t name; 176 dns_offsets_t offsets; 177 isc_region_t sr; 178 179 REQUIRE(rdata->type == 33); 180 REQUIRE(rdata->length != 0); 181 182 dns_compress_setmethods(cctx, DNS_COMPRESS_NONE); 183 /* 184 * Priority, weight, port. 185 */ 186 dns_rdata_toregion(rdata, &sr); 187 RETERR(mem_tobuffer(target, sr.base, 6)); 188 isc_region_consume(&sr, 6); 189 190 /* 191 * Target. 192 */ 193 dns_name_init(&name, offsets); 194 dns_name_fromregion(&name, &sr); 195 return (dns_name_towire(&name, cctx, target)); 196} 197 198static inline int 199compare_in_srv(ARGS_COMPARE) { 200 dns_name_t name1; 201 dns_name_t name2; 202 isc_region_t region1; 203 isc_region_t region2; 204 int order; 205 206 REQUIRE(rdata1->type == rdata2->type); 207 REQUIRE(rdata1->rdclass == rdata2->rdclass); 208 REQUIRE(rdata1->type == 33); 209 REQUIRE(rdata1->rdclass == 1); 210 REQUIRE(rdata1->length != 0); 211 REQUIRE(rdata2->length != 0); 212 213 /* 214 * Priority, weight, port. 215 */ 216 order = memcmp(rdata1->data, rdata2->data, 6); 217 if (order != 0) 218 return (order < 0 ? -1 : 1); 219 220 /* 221 * Target. 222 */ 223 dns_name_init(&name1, NULL); 224 dns_name_init(&name2, NULL); 225 226 dns_rdata_toregion(rdata1, ®ion1); 227 dns_rdata_toregion(rdata2, ®ion2); 228 229 isc_region_consume(®ion1, 6); 230 isc_region_consume(®ion2, 6); 231 232 dns_name_fromregion(&name1, ®ion1); 233 dns_name_fromregion(&name2, ®ion2); 234 235 return (dns_name_rdatacompare(&name1, &name2)); 236} 237 238static inline isc_result_t 239fromstruct_in_srv(ARGS_FROMSTRUCT) { 240 dns_rdata_in_srv_t *srv = source; 241 isc_region_t region; 242 243 REQUIRE(type == 33); 244 REQUIRE(rdclass == 1); 245 REQUIRE(source != NULL); 246 REQUIRE(srv->common.rdtype == type); 247 REQUIRE(srv->common.rdclass == rdclass); 248 249 UNUSED(type); 250 UNUSED(rdclass); 251 252 RETERR(uint16_tobuffer(srv->priority, target)); 253 RETERR(uint16_tobuffer(srv->weight, target)); 254 RETERR(uint16_tobuffer(srv->port, target)); 255 dns_name_toregion(&srv->target, ®ion); 256 return (isc_buffer_copyregion(target, ®ion)); 257} 258 259static inline isc_result_t 260tostruct_in_srv(ARGS_TOSTRUCT) { 261 isc_region_t region; 262 dns_rdata_in_srv_t *srv = target; 263 dns_name_t name; 264 265 REQUIRE(rdata->rdclass == 1); 266 REQUIRE(rdata->type == 33); 267 REQUIRE(target != NULL); 268 REQUIRE(rdata->length != 0); 269 270 srv->common.rdclass = rdata->rdclass; 271 srv->common.rdtype = rdata->type; 272 ISC_LINK_INIT(&srv->common, link); 273 274 dns_name_init(&name, NULL); 275 dns_rdata_toregion(rdata, ®ion); 276 srv->priority = uint16_fromregion(®ion); 277 isc_region_consume(®ion, 2); 278 srv->weight = uint16_fromregion(®ion); 279 isc_region_consume(®ion, 2); 280 srv->port = uint16_fromregion(®ion); 281 isc_region_consume(®ion, 2); 282 dns_name_fromregion(&name, ®ion); 283 dns_name_init(&srv->target, NULL); 284 RETERR(name_duporclone(&name, mctx, &srv->target)); 285 srv->mctx = mctx; 286 return (ISC_R_SUCCESS); 287} 288 289static inline void 290freestruct_in_srv(ARGS_FREESTRUCT) { 291 dns_rdata_in_srv_t *srv = source; 292 293 REQUIRE(source != NULL); 294 REQUIRE(srv->common.rdclass == 1); 295 REQUIRE(srv->common.rdtype == 33); 296 297 if (srv->mctx == NULL) 298 return; 299 300 dns_name_free(&srv->target, srv->mctx); 301 srv->mctx = NULL; 302} 303 304static inline isc_result_t 305additionaldata_in_srv(ARGS_ADDLDATA) { 306 dns_name_t name; 307 dns_offsets_t offsets; 308 isc_region_t region; 309 310 REQUIRE(rdata->type == 33); 311 REQUIRE(rdata->rdclass == 1); 312 313 dns_name_init(&name, offsets); 314 dns_rdata_toregion(rdata, ®ion); 315 isc_region_consume(®ion, 6); 316 dns_name_fromregion(&name, ®ion); 317 318 return ((add)(arg, &name, dns_rdatatype_a)); 319} 320 321static inline isc_result_t 322digest_in_srv(ARGS_DIGEST) { 323 isc_region_t r1, r2; 324 dns_name_t name; 325 326 REQUIRE(rdata->type == 33); 327 REQUIRE(rdata->rdclass == 1); 328 329 dns_rdata_toregion(rdata, &r1); 330 r2 = r1; 331 isc_region_consume(&r2, 6); 332 r1.length = 6; 333 RETERR((digest)(arg, &r1)); 334 dns_name_init(&name, NULL); 335 dns_name_fromregion(&name, &r2); 336 return (dns_name_digest(&name, digest, arg)); 337} 338 339static inline isc_boolean_t 340checkowner_in_srv(ARGS_CHECKOWNER) { 341 342 REQUIRE(type == 33); 343 REQUIRE(rdclass == 1); 344 345 UNUSED(name); 346 UNUSED(type); 347 UNUSED(rdclass); 348 UNUSED(wildcard); 349 350 return (ISC_TRUE); 351} 352 353static inline isc_boolean_t 354checknames_in_srv(ARGS_CHECKNAMES) { 355 isc_region_t region; 356 dns_name_t name; 357 358 REQUIRE(rdata->type == 33); 359 REQUIRE(rdata->rdclass == 1); 360 361 UNUSED(owner); 362 363 dns_rdata_toregion(rdata, ®ion); 364 isc_region_consume(®ion, 6); 365 dns_name_init(&name, NULL); 366 dns_name_fromregion(&name, ®ion); 367 if (!dns_name_ishostname(&name, ISC_FALSE)) { 368 if (bad != NULL) 369 dns_name_clone(&name, bad); 370 return (ISC_FALSE); 371 } 372 return (ISC_TRUE); 373} 374 375static inline int 376casecompare_in_srv(ARGS_COMPARE) { 377 return (compare_in_srv(rdata1, rdata2)); 378} 379 380#endif /* RDATA_IN_1_SRV_33_C */ 381