1 /* $NetBSD: lp_107.c,v 1.8 2024/02/21 22:52:13 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16 #ifndef RDATA_GENERIC_LP_107_C 17 #define RDATA_GENERIC_LP_107_C 18 19 #include <string.h> 20 21 #include <isc/net.h> 22 23 #define RRTYPE_LP_ATTRIBUTES (0) 24 25 static isc_result_t 26 fromtext_lp(ARGS_FROMTEXT) { 27 isc_token_t token; 28 dns_name_t name; 29 isc_buffer_t buffer; 30 31 REQUIRE(type == dns_rdatatype_lp); 32 33 UNUSED(type); 34 UNUSED(rdclass); 35 UNUSED(callbacks); 36 37 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 38 false)); 39 if (token.value.as_ulong > 0xffffU) { 40 RETTOK(ISC_R_RANGE); 41 } 42 RETERR(uint16_tobuffer(token.value.as_ulong, target)); 43 44 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 45 false)); 46 47 dns_name_init(&name, NULL); 48 buffer_fromregion(&buffer, &token.value.as_region); 49 if (origin == NULL) { 50 origin = dns_rootname; 51 } 52 return (dns_name_fromtext(&name, &buffer, origin, options, target)); 53 } 54 55 static isc_result_t 56 totext_lp(ARGS_TOTEXT) { 57 isc_region_t region; 58 dns_name_t name; 59 dns_name_t prefix; 60 bool sub; 61 char buf[sizeof("64000")]; 62 unsigned short num; 63 64 REQUIRE(rdata->type == dns_rdatatype_lp); 65 REQUIRE(rdata->length != 0); 66 67 dns_name_init(&name, NULL); 68 dns_name_init(&prefix, NULL); 69 70 dns_rdata_toregion(rdata, ®ion); 71 num = uint16_fromregion(®ion); 72 isc_region_consume(®ion, 2); 73 snprintf(buf, sizeof(buf), "%u", num); 74 RETERR(str_totext(buf, target)); 75 76 RETERR(str_totext(" ", target)); 77 78 dns_name_fromregion(&name, ®ion); 79 sub = name_prefix(&name, tctx->origin, &prefix); 80 return (dns_name_totext(&prefix, sub, target)); 81 } 82 83 static isc_result_t 84 fromwire_lp(ARGS_FROMWIRE) { 85 dns_name_t name; 86 isc_region_t sregion; 87 88 REQUIRE(type == dns_rdatatype_lp); 89 90 UNUSED(type); 91 UNUSED(rdclass); 92 93 dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14); 94 95 dns_name_init(&name, NULL); 96 97 isc_buffer_activeregion(source, &sregion); 98 if (sregion.length < 2) { 99 return (ISC_R_UNEXPECTEDEND); 100 } 101 RETERR(mem_tobuffer(target, sregion.base, 2)); 102 isc_buffer_forward(source, 2); 103 return (dns_name_fromwire(&name, source, dctx, options, target)); 104 } 105 106 static isc_result_t 107 towire_lp(ARGS_TOWIRE) { 108 REQUIRE(rdata->type == dns_rdatatype_lp); 109 REQUIRE(rdata->length != 0); 110 111 UNUSED(cctx); 112 113 return (mem_tobuffer(target, rdata->data, rdata->length)); 114 } 115 116 static int 117 compare_lp(ARGS_COMPARE) { 118 isc_region_t region1; 119 isc_region_t region2; 120 121 REQUIRE(rdata1->type == rdata2->type); 122 REQUIRE(rdata1->rdclass == rdata2->rdclass); 123 REQUIRE(rdata1->type == dns_rdatatype_lp); 124 REQUIRE(rdata1->length != 0); 125 REQUIRE(rdata2->length != 0); 126 127 dns_rdata_toregion(rdata1, ®ion1); 128 dns_rdata_toregion(rdata2, ®ion2); 129 130 return (isc_region_compare(®ion1, ®ion2)); 131 } 132 133 static isc_result_t 134 fromstruct_lp(ARGS_FROMSTRUCT) { 135 dns_rdata_lp_t *lp = source; 136 isc_region_t region; 137 138 REQUIRE(type == dns_rdatatype_lp); 139 REQUIRE(lp != NULL); 140 REQUIRE(lp->common.rdtype == type); 141 REQUIRE(lp->common.rdclass == rdclass); 142 143 UNUSED(type); 144 UNUSED(rdclass); 145 146 RETERR(uint16_tobuffer(lp->pref, target)); 147 dns_name_toregion(&lp->lp, ®ion); 148 return (isc_buffer_copyregion(target, ®ion)); 149 } 150 151 static isc_result_t 152 tostruct_lp(ARGS_TOSTRUCT) { 153 isc_region_t region; 154 dns_rdata_lp_t *lp = target; 155 dns_name_t name; 156 157 REQUIRE(rdata->type == dns_rdatatype_lp); 158 REQUIRE(lp != NULL); 159 REQUIRE(rdata->length != 0); 160 161 lp->common.rdclass = rdata->rdclass; 162 lp->common.rdtype = rdata->type; 163 ISC_LINK_INIT(&lp->common, link); 164 165 dns_name_init(&name, NULL); 166 dns_rdata_toregion(rdata, ®ion); 167 lp->pref = uint16_fromregion(®ion); 168 isc_region_consume(®ion, 2); 169 dns_name_fromregion(&name, ®ion); 170 dns_name_init(&lp->lp, NULL); 171 name_duporclone(&name, mctx, &lp->lp); 172 lp->mctx = mctx; 173 return (ISC_R_SUCCESS); 174 } 175 176 static void 177 freestruct_lp(ARGS_FREESTRUCT) { 178 dns_rdata_lp_t *lp = source; 179 180 REQUIRE(lp != NULL); 181 REQUIRE(lp->common.rdtype == dns_rdatatype_lp); 182 183 if (lp->mctx == NULL) { 184 return; 185 } 186 187 dns_name_free(&lp->lp, lp->mctx); 188 lp->mctx = NULL; 189 } 190 191 static isc_result_t 192 additionaldata_lp(ARGS_ADDLDATA) { 193 dns_name_t name; 194 dns_offsets_t offsets; 195 isc_region_t region; 196 isc_result_t result; 197 198 REQUIRE(rdata->type == dns_rdatatype_lp); 199 200 UNUSED(owner); 201 202 dns_name_init(&name, offsets); 203 dns_rdata_toregion(rdata, ®ion); 204 isc_region_consume(®ion, 2); 205 dns_name_fromregion(&name, ®ion); 206 207 result = (add)(arg, &name, dns_rdatatype_l32, NULL); 208 if (result != ISC_R_SUCCESS) { 209 return (result); 210 } 211 return ((add)(arg, &name, dns_rdatatype_l64, NULL)); 212 } 213 214 static isc_result_t 215 digest_lp(ARGS_DIGEST) { 216 isc_region_t region; 217 218 REQUIRE(rdata->type == dns_rdatatype_lp); 219 220 dns_rdata_toregion(rdata, ®ion); 221 return ((digest)(arg, ®ion)); 222 } 223 224 static bool 225 checkowner_lp(ARGS_CHECKOWNER) { 226 REQUIRE(type == dns_rdatatype_lp); 227 228 UNUSED(type); 229 UNUSED(rdclass); 230 UNUSED(name); 231 UNUSED(wildcard); 232 233 return (true); 234 } 235 236 static bool 237 checknames_lp(ARGS_CHECKNAMES) { 238 REQUIRE(rdata->type == dns_rdatatype_lp); 239 240 UNUSED(bad); 241 UNUSED(owner); 242 243 return (true); 244 } 245 246 static int 247 casecompare_lp(ARGS_COMPARE) { 248 dns_name_t name1; 249 dns_name_t name2; 250 isc_region_t region1; 251 isc_region_t region2; 252 int order; 253 254 REQUIRE(rdata1->type == rdata2->type); 255 REQUIRE(rdata1->rdclass == rdata2->rdclass); 256 REQUIRE(rdata1->type == dns_rdatatype_lp); 257 REQUIRE(rdata1->length != 0); 258 REQUIRE(rdata2->length != 0); 259 260 order = memcmp(rdata1->data, rdata2->data, 2); 261 if (order != 0) { 262 return (order < 0 ? -1 : 1); 263 } 264 265 dns_name_init(&name1, NULL); 266 dns_name_init(&name2, NULL); 267 268 dns_rdata_toregion(rdata1, ®ion1); 269 dns_rdata_toregion(rdata2, ®ion2); 270 271 isc_region_consume(®ion1, 2); 272 isc_region_consume(®ion2, 2); 273 274 dns_name_fromregion(&name1, ®ion1); 275 dns_name_fromregion(&name2, ®ion2); 276 277 return (dns_name_rdatacompare(&name1, &name2)); 278 } 279 280 #endif /* RDATA_GENERIC_LP_107_C */ 281