/contrib/bind9/lib/dns/rdata/generic/loc_29.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 804 lines · 627 code · 87 blank · 90 comment · 299 complexity · 09fe18e35ce05acabb87f3a854311a70 MD5 · raw file

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