1/* 2 * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") 3 * Copyright (C) 1999-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: loc_29.c,v 1.50 2009/12/04 21:09:33 marka Exp $ */ 19 20/* Reviewed: Wed Mar 15 18:13:09 PST 2000 by explorer */ 21 22/* RFC1876 */ 23 24#ifndef RDATA_GENERIC_LOC_29_C 25#define RDATA_GENERIC_LOC_29_C 26 27#define RRTYPE_LOC_ATTRIBUTES (0) 28 29static inline isc_result_t 30fromtext_loc(ARGS_FROMTEXT) { 31 isc_token_t token; 32 int d1, m1, s1; 33 int d2, m2, s2; 34 unsigned char size; 35 unsigned char hp; 36 unsigned char vp; 37 unsigned char version; 38 isc_boolean_t east = ISC_FALSE; 39 isc_boolean_t north = ISC_FALSE; 40 long tmp; 41 long m; 42 long cm; 43 long poweroften[8] = { 1, 10, 100, 1000, 44 10000, 100000, 1000000, 10000000 }; 45 int man; 46 int exp; 47 char *e; 48 int i; 49 unsigned long latitude; 50 unsigned long longitude; 51 unsigned long altitude; 52 53 REQUIRE(type == 29); 54 55 UNUSED(type); 56 UNUSED(rdclass); 57 UNUSED(origin); 58 UNUSED(options); 59 60 /* 61 * Defaults. 62 */ 63 m1 = s1 = 0; 64 m2 = s2 = 0; 65 size = 0x12; /* 1.00m */ 66 hp = 0x16; /* 10000.00 m */ 67 vp = 0x13; /* 10.00 m */ 68 version = 0; 69 70 /* 71 * Degrees. 72 */ 73 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 74 ISC_FALSE)); 75 if (token.value.as_ulong > 90U) 76 RETTOK(ISC_R_RANGE); 77 d1 = (int)token.value.as_ulong; 78 /* 79 * Minutes. 80 */ 81 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 82 ISC_FALSE)); 83 if (strcasecmp(DNS_AS_STR(token), "N") == 0) 84 north = ISC_TRUE; 85 if (north || strcasecmp(DNS_AS_STR(token), "S") == 0) 86 goto getlong; 87 m1 = strtol(DNS_AS_STR(token), &e, 10); 88 if (*e != 0) 89 RETTOK(DNS_R_SYNTAX); 90 if (m1 < 0 || m1 > 59) 91 RETTOK(ISC_R_RANGE); 92 if (d1 == 90 && m1 != 0) 93 RETTOK(ISC_R_RANGE); 94 95 /* 96 * Seconds. 97 */ 98 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 99 ISC_FALSE)); 100 if (strcasecmp(DNS_AS_STR(token), "N") == 0) 101 north = ISC_TRUE; 102 if (north || strcasecmp(DNS_AS_STR(token), "S") == 0) 103 goto getlong; 104 s1 = strtol(DNS_AS_STR(token), &e, 10); 105 if (*e != 0 && *e != '.') 106 RETTOK(DNS_R_SYNTAX); 107 if (s1 < 0 || s1 > 59) 108 RETTOK(ISC_R_RANGE); 109 if (*e == '.') { 110 const char *l; 111 e++; 112 for (i = 0; i < 3; i++) { 113 if (*e == 0) 114 break; 115 if ((tmp = decvalue(*e++)) < 0) 116 RETTOK(DNS_R_SYNTAX); 117 s1 *= 10; 118 s1 += tmp; 119 } 120 for (; i < 3; i++) 121 s1 *= 10; 122 l = e; 123 while (*e != 0) { 124 if (decvalue(*e++) < 0) 125 RETTOK(DNS_R_SYNTAX); 126 } 127 if (*l != '\0' && callbacks != NULL) { 128 const char *file = isc_lex_getsourcename(lexer); 129 unsigned long line = isc_lex_getsourceline(lexer); 130 131 if (file == NULL) 132 file = "UNKNOWN"; 133 (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra " 134 "precision digits ignored", 135 "dns_rdata_fromtext", file, line, 136 DNS_AS_STR(token)); 137 } 138 } else 139 s1 *= 1000; 140 if (d1 == 90 && s1 != 0) 141 RETTOK(ISC_R_RANGE); 142 143 /* 144 * Direction. 145 */ 146 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 147 ISC_FALSE)); 148 if (strcasecmp(DNS_AS_STR(token), "N") == 0) 149 north = ISC_TRUE; 150 if (!north && strcasecmp(DNS_AS_STR(token), "S") != 0) 151 RETTOK(DNS_R_SYNTAX); 152 153 getlong: 154 /* 155 * Degrees. 156 */ 157 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, 158 ISC_FALSE)); 159 if (token.value.as_ulong > 180U) 160 RETTOK(ISC_R_RANGE); 161 d2 = (int)token.value.as_ulong; 162 163 /* 164 * Minutes. 165 */ 166 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 167 ISC_FALSE)); 168 if (strcasecmp(DNS_AS_STR(token), "E") == 0) 169 east = ISC_TRUE; 170 if (east || strcasecmp(DNS_AS_STR(token), "W") == 0) 171 goto getalt; 172 m2 = strtol(DNS_AS_STR(token), &e, 10); 173 if (*e != 0) 174 RETTOK(DNS_R_SYNTAX); 175 if (m2 < 0 || m2 > 59) 176 RETTOK(ISC_R_RANGE); 177 if (d2 == 180 && m2 != 0) 178 RETTOK(ISC_R_RANGE); 179 180 /* 181 * Seconds. 182 */ 183 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 184 ISC_FALSE)); 185 if (strcasecmp(DNS_AS_STR(token), "E") == 0) 186 east = ISC_TRUE; 187 if (east || strcasecmp(DNS_AS_STR(token), "W") == 0) 188 goto getalt; 189 s2 = strtol(DNS_AS_STR(token), &e, 10); 190 if (*e != 0 && *e != '.') 191 RETTOK(DNS_R_SYNTAX); 192 if (s2 < 0 || s2 > 59) 193 RETTOK(ISC_R_RANGE); 194 if (*e == '.') { 195 const char *l; 196 e++; 197 for (i = 0; i < 3; i++) { 198 if (*e == 0) 199 break; 200 if ((tmp = decvalue(*e++)) < 0) 201 RETTOK(DNS_R_SYNTAX); 202 s2 *= 10; 203 s2 += tmp; 204 } 205 for (; i < 3; i++) 206 s2 *= 10; 207 l = e; 208 while (*e != 0) { 209 if (decvalue(*e++) < 0) 210 RETTOK(DNS_R_SYNTAX); 211 } 212 if (*l != '\0' && callbacks != NULL) { 213 const char *file = isc_lex_getsourcename(lexer); 214 unsigned long line = isc_lex_getsourceline(lexer); 215 216 if (file == NULL) 217 file = "UNKNOWN"; 218 (*callbacks->warn)(callbacks, "%s: %s:%u: '%s' extra " 219 "precision digits ignored", 220 "dns_rdata_fromtext", 221 file, line, DNS_AS_STR(token)); 222 } 223 } else 224 s2 *= 1000; 225 if (d2 == 180 && s2 != 0) 226 RETTOK(ISC_R_RANGE); 227 228 /* 229 * Direction. 230 */ 231 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 232 ISC_FALSE)); 233 if (strcasecmp(DNS_AS_STR(token), "E") == 0) 234 east = ISC_TRUE; 235 if (!east && strcasecmp(DNS_AS_STR(token), "W") != 0) 236 RETTOK(DNS_R_SYNTAX); 237 238 getalt: 239 /* 240 * Altitude. 241 */ 242 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 243 ISC_FALSE)); 244 m = strtol(DNS_AS_STR(token), &e, 10); 245 if (*e != 0 && *e != '.' && *e != 'm') 246 RETTOK(DNS_R_SYNTAX); 247 if (m < -100000 || m > 42849672) 248 RETTOK(ISC_R_RANGE); 249 cm = 0; 250 if (*e == '.') { 251 e++; 252 for (i = 0; i < 2; i++) { 253 if (*e == 0 || *e == 'm') 254 break; 255 if ((tmp = decvalue(*e++)) < 0) 256 return (DNS_R_SYNTAX); 257 cm *= 10; 258 if (m < 0) 259 cm -= tmp; 260 else 261 cm += tmp; 262 } 263 for (; i < 2; i++) 264 cm *= 10; 265 } 266 if (*e == 'm') 267 e++; 268 if (*e != 0) 269 RETTOK(DNS_R_SYNTAX); 270 if (m == -100000 && cm != 0) 271 RETTOK(ISC_R_RANGE); 272 if (m == 42849672 && cm > 95) 273 RETTOK(ISC_R_RANGE); 274 /* 275 * Adjust base. 276 */ 277 altitude = m + 100000; 278 altitude *= 100; 279 altitude += cm; 280 281 /* 282 * Size: optional. 283 */ 284 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 285 ISC_TRUE)); 286 if (token.type == isc_tokentype_eol || 287 token.type == isc_tokentype_eof) { 288 isc_lex_ungettoken(lexer, &token); 289 goto encode; 290 } 291 m = strtol(DNS_AS_STR(token), &e, 10); 292 if (*e != 0 && *e != '.' && *e != 'm') 293 RETTOK(DNS_R_SYNTAX); 294 if (m < 0 || m > 90000000) 295 RETTOK(ISC_R_RANGE); 296 cm = 0; 297 if (*e == '.') { 298 e++; 299 for (i = 0; i < 2; i++) { 300 if (*e == 0 || *e == 'm') 301 break; 302 if ((tmp = decvalue(*e++)) < 0) 303 RETTOK(DNS_R_SYNTAX); 304 cm *= 10; 305 cm += tmp; 306 } 307 for (; i < 2; i++) 308 cm *= 10; 309 } 310 if (*e == 'm') 311 e++; 312 if (*e != 0) 313 RETTOK(DNS_R_SYNTAX); 314 /* 315 * We don't just multiply out as we will overflow. 316 */ 317 if (m > 0) { 318 for (exp = 0; exp < 7; exp++) 319 if (m < poweroften[exp+1]) 320 break; 321 man = m / poweroften[exp]; 322 exp += 2; 323 } else { 324 if (cm >= 10) { 325 man = cm / 10; 326 exp = 1; 327 } else { 328 man = cm; 329 exp = 0; 330 } 331 } 332 size = (man << 4) + exp; 333 334 /* 335 * Horizontal precision: optional. 336 */ 337 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 338 ISC_TRUE)); 339 if (token.type == isc_tokentype_eol || 340 token.type == isc_tokentype_eof) { 341 isc_lex_ungettoken(lexer, &token); 342 goto encode; 343 } 344 m = strtol(DNS_AS_STR(token), &e, 10); 345 if (*e != 0 && *e != '.' && *e != 'm') 346 RETTOK(DNS_R_SYNTAX); 347 if (m < 0 || m > 90000000) 348 RETTOK(ISC_R_RANGE); 349 cm = 0; 350 if (*e == '.') { 351 e++; 352 for (i = 0; i < 2; i++) { 353 if (*e == 0 || *e == 'm') 354 break; 355 if ((tmp = decvalue(*e++)) < 0) 356 RETTOK(DNS_R_SYNTAX); 357 cm *= 10; 358 cm += tmp; 359 } 360 for (; i < 2; i++) 361 cm *= 10; 362 } 363 if (*e == 'm') 364 e++; 365 if (*e != 0) 366 RETTOK(DNS_R_SYNTAX); 367 /* 368 * We don't just multiply out as we will overflow. 369 */ 370 if (m > 0) { 371 for (exp = 0; exp < 7; exp++) 372 if (m < poweroften[exp+1]) 373 break; 374 man = m / poweroften[exp]; 375 exp += 2; 376 } else if (cm >= 10) { 377 man = cm / 10; 378 exp = 1; 379 } else { 380 man = cm; 381 exp = 0; 382 } 383 hp = (man << 4) + exp; 384 385 /* 386 * Vertical precision: optional. 387 */ 388 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string, 389 ISC_TRUE)); 390 if (token.type == isc_tokentype_eol || 391 token.type == isc_tokentype_eof) { 392 isc_lex_ungettoken(lexer, &token); 393 goto encode; 394 } 395 m = strtol(DNS_AS_STR(token), &e, 10); 396 if (*e != 0 && *e != '.' && *e != 'm') 397 RETTOK(DNS_R_SYNTAX); 398 if (m < 0 || m > 90000000) 399 RETTOK(ISC_R_RANGE); 400 cm = 0; 401 if (*e == '.') { 402 e++; 403 for (i = 0; i < 2; i++) { 404 if (*e == 0 || *e == 'm') 405 break; 406 if ((tmp = decvalue(*e++)) < 0) 407 RETTOK(DNS_R_SYNTAX); 408 cm *= 10; 409 cm += tmp; 410 } 411 for (; i < 2; i++) 412 cm *= 10; 413 } 414 if (*e == 'm') 415 e++; 416 if (*e != 0) 417 RETTOK(DNS_R_SYNTAX); 418 /* 419 * We don't just multiply out as we will overflow. 420 */ 421 if (m > 0) { 422 for (exp = 0; exp < 7; exp++) 423 if (m < poweroften[exp+1]) 424 break; 425 man = m / poweroften[exp]; 426 exp += 2; 427 } else if (cm >= 10) { 428 man = cm / 10; 429 exp = 1; 430 } else { 431 man = cm; 432 exp = 0; 433 } 434 vp = (man << 4) + exp; 435 436 encode: 437 RETERR(mem_tobuffer(target, &version, 1)); 438 RETERR(mem_tobuffer(target, &size, 1)); 439 RETERR(mem_tobuffer(target, &hp, 1)); 440 RETERR(mem_tobuffer(target, &vp, 1)); 441 if (north) 442 latitude = 0x80000000 + ( d1 * 3600 + m1 * 60 ) * 1000 + s1; 443 else 444 latitude = 0x80000000 - ( d1 * 3600 + m1 * 60 ) * 1000 - s1; 445 RETERR(uint32_tobuffer(latitude, target)); 446 447 if (east) 448 longitude = 0x80000000 + ( d2 * 3600 + m2 * 60 ) * 1000 + s2; 449 else 450 longitude = 0x80000000 - ( d2 * 3600 + m2 * 60 ) * 1000 - s2; 451 RETERR(uint32_tobuffer(longitude, target)); 452 453 return (uint32_tobuffer(altitude, target)); 454} 455 456static inline isc_result_t 457totext_loc(ARGS_TOTEXT) { 458 int d1, m1, s1, fs1; 459 int d2, m2, s2, fs2; 460 unsigned long latitude; 461 unsigned long longitude; 462 unsigned long altitude; 463 isc_boolean_t north; 464 isc_boolean_t east; 465 isc_boolean_t below; 466 isc_region_t sr; 467 char buf[sizeof("89 59 59.999 N 179 59 59.999 E " 468 "42849672.95m 90000000m 90000000m 90000000m")]; 469 char sbuf[sizeof("90000000m")]; 470 char hbuf[sizeof("90000000m")]; 471 char vbuf[sizeof("90000000m")]; 472 unsigned char size, hp, vp; 473 unsigned long poweroften[8] = { 1, 10, 100, 1000, 474 10000, 100000, 1000000, 10000000 }; 475 476 UNUSED(tctx); 477 478 REQUIRE(rdata->type == 29); 479 REQUIRE(rdata->length != 0); 480 481 dns_rdata_toregion(rdata, &sr); 482 483 /* version = sr.base[0]; */ 484 size = sr.base[1]; 485 INSIST((size&0x0f) < 10 && (size>>4) < 10); 486 if ((size&0x0f)> 1) 487 sprintf(sbuf, "%lum", (size>>4) * poweroften[(size&0x0f)-2]); 488 else 489 sprintf(sbuf, "0.%02lum", (size>>4) * poweroften[(size&0x0f)]); 490 hp = sr.base[2]; 491 INSIST((hp&0x0f) < 10 && (hp>>4) < 10); 492 if ((hp&0x0f)> 1) 493 sprintf(hbuf, "%lum", (hp>>4) * poweroften[(hp&0x0f)-2]); 494 else 495 sprintf(hbuf, "0.%02lum", (hp>>4) * poweroften[(hp&0x0f)]); 496 vp = sr.base[3]; 497 INSIST((vp&0x0f) < 10 && (vp>>4) < 10); 498 if ((vp&0x0f)> 1) 499 sprintf(vbuf, "%lum", (vp>>4) * poweroften[(vp&0x0f)-2]); 500 else 501 sprintf(vbuf, "0.%02lum", (vp>>4) * poweroften[(vp&0x0f)]); 502 isc_region_consume(&sr, 4); 503 504 latitude = uint32_fromregion(&sr); 505 isc_region_consume(&sr, 4); 506 if (latitude >= 0x80000000) { 507 north = ISC_TRUE; 508 latitude -= 0x80000000; 509 } else { 510 north = ISC_FALSE; 511 latitude = 0x80000000 - latitude; 512 } 513 fs1 = (int)(latitude % 1000); 514 latitude /= 1000; 515 s1 = (int)(latitude % 60); 516 latitude /= 60; 517 m1 = (int)(latitude % 60); 518 latitude /= 60; 519 d1 = (int)latitude; 520 INSIST(latitude <= 90U); 521 522 longitude = uint32_fromregion(&sr); 523 isc_region_consume(&sr, 4); 524 if (longitude >= 0x80000000) { 525 east = ISC_TRUE; 526 longitude -= 0x80000000; 527 } else { 528 east = ISC_FALSE; 529 longitude = 0x80000000 - longitude; 530 } 531 fs2 = (int)(longitude % 1000); 532 longitude /= 1000; 533 s2 = (int)(longitude % 60); 534 longitude /= 60; 535 m2 = (int)(longitude % 60); 536 longitude /= 60; 537 d2 = (int)longitude; 538 INSIST(longitude <= 180U); 539 540 altitude = uint32_fromregion(&sr); 541 isc_region_consume(&sr, 4); 542 if (altitude < 10000000U) { 543 below = ISC_TRUE; 544 altitude = 10000000 - altitude; 545 } else { 546 below =ISC_FALSE; 547 altitude -= 10000000; 548 } 549 550 sprintf(buf, "%d %d %d.%03d %s %d %d %d.%03d %s %s%ld.%02ldm %s %s %s", 551 d1, m1, s1, fs1, north ? "N" : "S", 552 d2, m2, s2, fs2, east ? "E" : "W", 553 below ? "-" : "", altitude/100, altitude % 100, 554 sbuf, hbuf, vbuf); 555 556 return (str_totext(buf, target)); 557} 558 559static inline isc_result_t 560fromwire_loc(ARGS_FROMWIRE) { 561 isc_region_t sr; 562 unsigned char c; 563 unsigned long latitude; 564 unsigned long longitude; 565 566 REQUIRE(type == 29); 567 568 UNUSED(type); 569 UNUSED(rdclass); 570 UNUSED(dctx); 571 UNUSED(options); 572 573 isc_buffer_activeregion(source, &sr); 574 if (sr.length < 1) 575 return (ISC_R_UNEXPECTEDEND); 576 if (sr.base[0] != 0) 577 return (ISC_R_NOTIMPLEMENTED); 578 if (sr.length < 16) 579 return (ISC_R_UNEXPECTEDEND); 580 581 /* 582 * Size. 583 */ 584 c = sr.base[1]; 585 if (c != 0) 586 if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) 587 return (ISC_R_RANGE); 588 589 /* 590 * Horizontal precision. 591 */ 592 c = sr.base[2]; 593 if (c != 0) 594 if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) 595 return (ISC_R_RANGE); 596 597 /* 598 * Vertical precision. 599 */ 600 c = sr.base[3]; 601 if (c != 0) 602 if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) 603 return (ISC_R_RANGE); 604 isc_region_consume(&sr, 4); 605 606 /* 607 * Latitude. 608 */ 609 latitude = uint32_fromregion(&sr); 610 if (latitude < (0x80000000UL - 90 * 3600000) || 611 latitude > (0x80000000UL + 90 * 3600000)) 612 return (ISC_R_RANGE); 613 isc_region_consume(&sr, 4); 614 615 /* 616 * Longitude. 617 */ 618 longitude = uint32_fromregion(&sr); 619 if (longitude < (0x80000000UL - 180 * 3600000) || 620 longitude > (0x80000000UL + 180 * 3600000)) 621 return (ISC_R_RANGE); 622 623 /* 624 * Altitude. 625 * All values possible. 626 */ 627 628 isc_buffer_activeregion(source, &sr); 629 isc_buffer_forward(source, 16); 630 return (mem_tobuffer(target, sr.base, 16)); 631} 632 633static inline isc_result_t 634towire_loc(ARGS_TOWIRE) { 635 UNUSED(cctx); 636 637 REQUIRE(rdata->type == 29); 638 REQUIRE(rdata->length != 0); 639 640 return (mem_tobuffer(target, rdata->data, rdata->length)); 641} 642 643static inline int 644compare_loc(ARGS_COMPARE) { 645 isc_region_t r1; 646 isc_region_t r2; 647 648 REQUIRE(rdata1->type == rdata2->type); 649 REQUIRE(rdata1->rdclass == rdata2->rdclass); 650 REQUIRE(rdata1->type == 29); 651 REQUIRE(rdata1->length != 0); 652 REQUIRE(rdata2->length != 0); 653 654 dns_rdata_toregion(rdata1, &r1); 655 dns_rdata_toregion(rdata2, &r2); 656 return (isc_region_compare(&r1, &r2)); 657} 658 659static inline isc_result_t 660fromstruct_loc(ARGS_FROMSTRUCT) { 661 dns_rdata_loc_t *loc = source; 662 isc_uint8_t c; 663 664 REQUIRE(type == 29); 665 REQUIRE(source != NULL); 666 REQUIRE(loc->common.rdtype == type); 667 REQUIRE(loc->common.rdclass == rdclass); 668 669 UNUSED(type); 670 UNUSED(rdclass); 671 672 if (loc->v.v0.version != 0) 673 return (ISC_R_NOTIMPLEMENTED); 674 RETERR(uint8_tobuffer(loc->v.v0.version, target)); 675 676 c = loc->v.v0.size; 677 if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) 678 return (ISC_R_RANGE); 679 RETERR(uint8_tobuffer(loc->v.v0.size, target)); 680 681 c = loc->v.v0.horizontal; 682 if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) 683 return (ISC_R_RANGE); 684 RETERR(uint8_tobuffer(loc->v.v0.horizontal, target)); 685 686 c = loc->v.v0.vertical; 687 if ((c&0xf) > 9 || ((c>>4)&0xf) > 9 || ((c>>4)&0xf) == 0) 688 return (ISC_R_RANGE); 689 RETERR(uint8_tobuffer(loc->v.v0.vertical, target)); 690 691 if (loc->v.v0.latitude < (0x80000000UL - 90 * 3600000) || 692 loc->v.v0.latitude > (0x80000000UL + 90 * 3600000)) 693 return (ISC_R_RANGE); 694 RETERR(uint32_tobuffer(loc->v.v0.latitude, target)); 695 696 if (loc->v.v0.longitude < (0x80000000UL - 180 * 3600000) || 697 loc->v.v0.longitude > (0x80000000UL + 180 * 3600000)) 698 return (ISC_R_RANGE); 699 RETERR(uint32_tobuffer(loc->v.v0.longitude, target)); 700 return (uint32_tobuffer(loc->v.v0.altitude, target)); 701} 702 703static inline isc_result_t 704tostruct_loc(ARGS_TOSTRUCT) { 705 dns_rdata_loc_t *loc = target; 706 isc_region_t r; 707 isc_uint8_t version; 708 709 REQUIRE(rdata->type == 29); 710 REQUIRE(target != NULL); 711 REQUIRE(rdata->length != 0); 712 713 UNUSED(mctx); 714 715 dns_rdata_toregion(rdata, &r); 716 version = uint8_fromregion(&r); 717 if (version != 0) 718 return (ISC_R_NOTIMPLEMENTED); 719 720 loc->common.rdclass = rdata->rdclass; 721 loc->common.rdtype = rdata->type; 722 ISC_LINK_INIT(&loc->common, link); 723 724 loc->v.v0.version = version; 725 isc_region_consume(&r, 1); 726 loc->v.v0.size = uint8_fromregion(&r); 727 isc_region_consume(&r, 1); 728 loc->v.v0.horizontal = uint8_fromregion(&r); 729 isc_region_consume(&r, 1); 730 loc->v.v0.vertical = uint8_fromregion(&r); 731 isc_region_consume(&r, 1); 732 loc->v.v0.latitude = uint32_fromregion(&r); 733 isc_region_consume(&r, 4); 734 loc->v.v0.longitude = uint32_fromregion(&r); 735 isc_region_consume(&r, 4); 736 loc->v.v0.altitude = uint32_fromregion(&r); 737 isc_region_consume(&r, 4); 738 return (ISC_R_SUCCESS); 739} 740 741static inline void 742freestruct_loc(ARGS_FREESTRUCT) { 743 dns_rdata_loc_t *loc = source; 744 745 REQUIRE(source != NULL); 746 REQUIRE(loc->common.rdtype == 29); 747 748 UNUSED(source); 749 UNUSED(loc); 750} 751 752static inline isc_result_t 753additionaldata_loc(ARGS_ADDLDATA) { 754 REQUIRE(rdata->type == 29); 755 756 UNUSED(rdata); 757 UNUSED(add); 758 UNUSED(arg); 759 760 return (ISC_R_SUCCESS); 761} 762 763static inline isc_result_t 764digest_loc(ARGS_DIGEST) { 765 isc_region_t r; 766 767 REQUIRE(rdata->type == 29); 768 769 dns_rdata_toregion(rdata, &r); 770 771 return ((digest)(arg, &r)); 772} 773 774static inline isc_boolean_t 775checkowner_loc(ARGS_CHECKOWNER) { 776 777 REQUIRE(type == 29); 778 779 UNUSED(name); 780 UNUSED(type); 781 UNUSED(rdclass); 782 UNUSED(wildcard); 783 784 return (ISC_TRUE); 785} 786 787static inline isc_boolean_t 788checknames_loc(ARGS_CHECKNAMES) { 789 790 REQUIRE(rdata->type == 29); 791 792 UNUSED(rdata); 793 UNUSED(owner); 794 UNUSED(bad); 795 796 return (ISC_TRUE); 797} 798 799static inline int 800casecompare_loc(ARGS_COMPARE) { 801 return (compare_loc(rdata1, rdata2)); 802} 803 804#endif /* RDATA_GENERIC_LOC_29_C */ 805