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