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

https://bitbucket.org/freebsd/freebsd-head/ · C · 449 lines · 328 code · 102 blank · 19 comment · 65 complexity · a7ee339973f54cef3660969c9e7cd967 MD5 · raw file

  1. /*
  2. * Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
  3. * Copyright (C) 1998-2002 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$ */
  18. /* Reviewed: Thu Mar 16 15:18:32 PST 2000 by explorer */
  19. #ifndef RDATA_GENERIC_SOA_6_C
  20. #define RDATA_GENERIC_SOA_6_C
  21. #define RRTYPE_SOA_ATTRIBUTES (DNS_RDATATYPEATTR_SINGLETON)
  22. static inline isc_result_t
  23. fromtext_soa(ARGS_FROMTEXT) {
  24. isc_token_t token;
  25. dns_name_t name;
  26. isc_buffer_t buffer;
  27. int i;
  28. isc_uint32_t n;
  29. isc_boolean_t ok;
  30. REQUIRE(type == 6);
  31. UNUSED(type);
  32. UNUSED(rdclass);
  33. UNUSED(callbacks);
  34. origin = (origin != NULL) ? origin : dns_rootname;
  35. for (i = 0; i < 2; i++) {
  36. RETERR(isc_lex_getmastertoken(lexer, &token,
  37. isc_tokentype_string,
  38. ISC_FALSE));
  39. dns_name_init(&name, NULL);
  40. buffer_fromregion(&buffer, &token.value.as_region);
  41. RETTOK(dns_name_fromtext(&name, &buffer, origin,
  42. options, target));
  43. ok = ISC_TRUE;
  44. if ((options & DNS_RDATA_CHECKNAMES) != 0)
  45. switch (i) {
  46. case 0:
  47. ok = dns_name_ishostname(&name, ISC_FALSE);
  48. break;
  49. case 1:
  50. ok = dns_name_ismailbox(&name);
  51. break;
  52. }
  53. if (!ok && (options & DNS_RDATA_CHECKNAMESFAIL) != 0)
  54. RETTOK(DNS_R_BADNAME);
  55. if (!ok && callbacks != NULL)
  56. warn_badname(&name, lexer, callbacks);
  57. }
  58. RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
  59. ISC_FALSE));
  60. RETERR(uint32_tobuffer(token.value.as_ulong, target));
  61. for (i = 0; i < 4; i++) {
  62. RETERR(isc_lex_getmastertoken(lexer, &token,
  63. isc_tokentype_string,
  64. ISC_FALSE));
  65. RETTOK(dns_counter_fromtext(&token.value.as_textregion, &n));
  66. RETERR(uint32_tobuffer(n, target));
  67. }
  68. return (ISC_R_SUCCESS);
  69. }
  70. static const char *soa_fieldnames[5] = {
  71. "serial", "refresh", "retry", "expire", "minimum"
  72. };
  73. static inline isc_result_t
  74. totext_soa(ARGS_TOTEXT) {
  75. isc_region_t dregion;
  76. dns_name_t mname;
  77. dns_name_t rname;
  78. dns_name_t prefix;
  79. isc_boolean_t sub;
  80. int i;
  81. isc_boolean_t multiline;
  82. isc_boolean_t comment;
  83. REQUIRE(rdata->type == 6);
  84. REQUIRE(rdata->length != 0);
  85. multiline = ISC_TF((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0);
  86. if (multiline)
  87. comment = ISC_TF((tctx->flags & DNS_STYLEFLAG_COMMENT) != 0);
  88. else
  89. comment = ISC_FALSE;
  90. dns_name_init(&mname, NULL);
  91. dns_name_init(&rname, NULL);
  92. dns_name_init(&prefix, NULL);
  93. dns_rdata_toregion(rdata, &dregion);
  94. dns_name_fromregion(&mname, &dregion);
  95. isc_region_consume(&dregion, name_length(&mname));
  96. dns_name_fromregion(&rname, &dregion);
  97. isc_region_consume(&dregion, name_length(&rname));
  98. sub = name_prefix(&mname, tctx->origin, &prefix);
  99. RETERR(dns_name_totext(&prefix, sub, target));
  100. RETERR(str_totext(" ", target));
  101. sub = name_prefix(&rname, tctx->origin, &prefix);
  102. RETERR(dns_name_totext(&prefix, sub, target));
  103. if (multiline)
  104. RETERR(str_totext(" (" , target));
  105. RETERR(str_totext(tctx->linebreak, target));
  106. for (i = 0; i < 5; i++) {
  107. char buf[sizeof("0123456789 ; ")];
  108. unsigned long num;
  109. num = uint32_fromregion(&dregion);
  110. isc_region_consume(&dregion, 4);
  111. sprintf(buf, comment ? "%-10lu ; " : "%lu", num);
  112. RETERR(str_totext(buf, target));
  113. if (comment) {
  114. RETERR(str_totext(soa_fieldnames[i], target));
  115. /* Print times in week/day/hour/minute/second form */
  116. if (i >= 1) {
  117. RETERR(str_totext(" (", target));
  118. RETERR(dns_ttl_totext(num, ISC_TRUE, target));
  119. RETERR(str_totext(")", target));
  120. }
  121. RETERR(str_totext(tctx->linebreak, target));
  122. } else if (i < 4) {
  123. RETERR(str_totext(tctx->linebreak, target));
  124. }
  125. }
  126. if (multiline)
  127. RETERR(str_totext(")", target));
  128. return (ISC_R_SUCCESS);
  129. }
  130. static inline isc_result_t
  131. fromwire_soa(ARGS_FROMWIRE) {
  132. dns_name_t mname;
  133. dns_name_t rname;
  134. isc_region_t sregion;
  135. isc_region_t tregion;
  136. REQUIRE(type == 6);
  137. UNUSED(type);
  138. UNUSED(rdclass);
  139. dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
  140. dns_name_init(&mname, NULL);
  141. dns_name_init(&rname, NULL);
  142. RETERR(dns_name_fromwire(&mname, source, dctx, options, target));
  143. RETERR(dns_name_fromwire(&rname, source, dctx, options, target));
  144. isc_buffer_activeregion(source, &sregion);
  145. isc_buffer_availableregion(target, &tregion);
  146. if (sregion.length < 20)
  147. return (ISC_R_UNEXPECTEDEND);
  148. if (tregion.length < 20)
  149. return (ISC_R_NOSPACE);
  150. memcpy(tregion.base, sregion.base, 20);
  151. isc_buffer_forward(source, 20);
  152. isc_buffer_add(target, 20);
  153. return (ISC_R_SUCCESS);
  154. }
  155. static inline isc_result_t
  156. towire_soa(ARGS_TOWIRE) {
  157. isc_region_t sregion;
  158. isc_region_t tregion;
  159. dns_name_t mname;
  160. dns_name_t rname;
  161. dns_offsets_t moffsets;
  162. dns_offsets_t roffsets;
  163. REQUIRE(rdata->type == 6);
  164. REQUIRE(rdata->length != 0);
  165. dns_compress_setmethods(cctx, DNS_COMPRESS_GLOBAL14);
  166. dns_name_init(&mname, moffsets);
  167. dns_name_init(&rname, roffsets);
  168. dns_rdata_toregion(rdata, &sregion);
  169. dns_name_fromregion(&mname, &sregion);
  170. isc_region_consume(&sregion, name_length(&mname));
  171. RETERR(dns_name_towire(&mname, cctx, target));
  172. dns_name_fromregion(&rname, &sregion);
  173. isc_region_consume(&sregion, name_length(&rname));
  174. RETERR(dns_name_towire(&rname, cctx, target));
  175. isc_buffer_availableregion(target, &tregion);
  176. if (tregion.length < 20)
  177. return (ISC_R_NOSPACE);
  178. memcpy(tregion.base, sregion.base, 20);
  179. isc_buffer_add(target, 20);
  180. return (ISC_R_SUCCESS);
  181. }
  182. static inline int
  183. compare_soa(ARGS_COMPARE) {
  184. isc_region_t region1;
  185. isc_region_t region2;
  186. dns_name_t name1;
  187. dns_name_t name2;
  188. int order;
  189. REQUIRE(rdata1->type == rdata2->type);
  190. REQUIRE(rdata1->rdclass == rdata2->rdclass);
  191. REQUIRE(rdata1->type == 6);
  192. REQUIRE(rdata1->length != 0);
  193. REQUIRE(rdata2->length != 0);
  194. dns_name_init(&name1, NULL);
  195. dns_name_init(&name2, NULL);
  196. dns_rdata_toregion(rdata1, &region1);
  197. dns_rdata_toregion(rdata2, &region2);
  198. dns_name_fromregion(&name1, &region1);
  199. dns_name_fromregion(&name2, &region2);
  200. order = dns_name_rdatacompare(&name1, &name2);
  201. if (order != 0)
  202. return (order);
  203. isc_region_consume(&region1, name_length(&name1));
  204. isc_region_consume(&region2, name_length(&name2));
  205. dns_name_init(&name1, NULL);
  206. dns_name_init(&name2, NULL);
  207. dns_name_fromregion(&name1, &region1);
  208. dns_name_fromregion(&name2, &region2);
  209. order = dns_name_rdatacompare(&name1, &name2);
  210. if (order != 0)
  211. return (order);
  212. isc_region_consume(&region1, name_length(&name1));
  213. isc_region_consume(&region2, name_length(&name2));
  214. return (isc_region_compare(&region1, &region2));
  215. }
  216. static inline isc_result_t
  217. fromstruct_soa(ARGS_FROMSTRUCT) {
  218. dns_rdata_soa_t *soa = source;
  219. isc_region_t region;
  220. REQUIRE(type == 6);
  221. REQUIRE(source != NULL);
  222. REQUIRE(soa->common.rdtype == type);
  223. REQUIRE(soa->common.rdclass == rdclass);
  224. UNUSED(type);
  225. UNUSED(rdclass);
  226. dns_name_toregion(&soa->origin, &region);
  227. RETERR(isc_buffer_copyregion(target, &region));
  228. dns_name_toregion(&soa->contact, &region);
  229. RETERR(isc_buffer_copyregion(target, &region));
  230. RETERR(uint32_tobuffer(soa->serial, target));
  231. RETERR(uint32_tobuffer(soa->refresh, target));
  232. RETERR(uint32_tobuffer(soa->retry, target));
  233. RETERR(uint32_tobuffer(soa->expire, target));
  234. return (uint32_tobuffer(soa->minimum, target));
  235. }
  236. static inline isc_result_t
  237. tostruct_soa(ARGS_TOSTRUCT) {
  238. isc_region_t region;
  239. dns_rdata_soa_t *soa = target;
  240. dns_name_t name;
  241. isc_result_t result;
  242. REQUIRE(rdata->type == 6);
  243. REQUIRE(target != NULL);
  244. REQUIRE(rdata->length != 0);
  245. soa->common.rdclass = rdata->rdclass;
  246. soa->common.rdtype = rdata->type;
  247. ISC_LINK_INIT(&soa->common, link);
  248. dns_rdata_toregion(rdata, &region);
  249. dns_name_init(&name, NULL);
  250. dns_name_fromregion(&name, &region);
  251. isc_region_consume(&region, name_length(&name));
  252. dns_name_init(&soa->origin, NULL);
  253. RETERR(name_duporclone(&name, mctx, &soa->origin));
  254. dns_name_fromregion(&name, &region);
  255. isc_region_consume(&region, name_length(&name));
  256. dns_name_init(&soa->contact, NULL);
  257. result = name_duporclone(&name, mctx, &soa->contact);
  258. if (result != ISC_R_SUCCESS)
  259. goto cleanup;
  260. soa->serial = uint32_fromregion(&region);
  261. isc_region_consume(&region, 4);
  262. soa->refresh = uint32_fromregion(&region);
  263. isc_region_consume(&region, 4);
  264. soa->retry = uint32_fromregion(&region);
  265. isc_region_consume(&region, 4);
  266. soa->expire = uint32_fromregion(&region);
  267. isc_region_consume(&region, 4);
  268. soa->minimum = uint32_fromregion(&region);
  269. soa->mctx = mctx;
  270. return (ISC_R_SUCCESS);
  271. cleanup:
  272. if (mctx != NULL)
  273. dns_name_free(&soa->origin, mctx);
  274. return (ISC_R_NOMEMORY);
  275. }
  276. static inline void
  277. freestruct_soa(ARGS_FREESTRUCT) {
  278. dns_rdata_soa_t *soa = source;
  279. REQUIRE(source != NULL);
  280. REQUIRE(soa->common.rdtype == 6);
  281. if (soa->mctx == NULL)
  282. return;
  283. dns_name_free(&soa->origin, soa->mctx);
  284. dns_name_free(&soa->contact, soa->mctx);
  285. soa->mctx = NULL;
  286. }
  287. static inline isc_result_t
  288. additionaldata_soa(ARGS_ADDLDATA) {
  289. UNUSED(rdata);
  290. UNUSED(add);
  291. UNUSED(arg);
  292. REQUIRE(rdata->type == 6);
  293. return (ISC_R_SUCCESS);
  294. }
  295. static inline isc_result_t
  296. digest_soa(ARGS_DIGEST) {
  297. isc_region_t r;
  298. dns_name_t name;
  299. REQUIRE(rdata->type == 6);
  300. dns_rdata_toregion(rdata, &r);
  301. dns_name_init(&name, NULL);
  302. dns_name_fromregion(&name, &r);
  303. RETERR(dns_name_digest(&name, digest, arg));
  304. isc_region_consume(&r, name_length(&name));
  305. dns_name_init(&name, NULL);
  306. dns_name_fromregion(&name, &r);
  307. RETERR(dns_name_digest(&name, digest, arg));
  308. isc_region_consume(&r, name_length(&name));
  309. return ((digest)(arg, &r));
  310. }
  311. static inline isc_boolean_t
  312. checkowner_soa(ARGS_CHECKOWNER) {
  313. REQUIRE(type == 6);
  314. UNUSED(name);
  315. UNUSED(type);
  316. UNUSED(rdclass);
  317. UNUSED(wildcard);
  318. return (ISC_TRUE);
  319. }
  320. static inline isc_boolean_t
  321. checknames_soa(ARGS_CHECKNAMES) {
  322. isc_region_t region;
  323. dns_name_t name;
  324. REQUIRE(rdata->type == 6);
  325. UNUSED(owner);
  326. dns_rdata_toregion(rdata, &region);
  327. dns_name_init(&name, NULL);
  328. dns_name_fromregion(&name, &region);
  329. if (!dns_name_ishostname(&name, ISC_FALSE)) {
  330. if (bad != NULL)
  331. dns_name_clone(&name, bad);
  332. return (ISC_FALSE);
  333. }
  334. isc_region_consume(&region, name_length(&name));
  335. dns_name_fromregion(&name, &region);
  336. if (!dns_name_ismailbox(&name)) {
  337. if (bad != NULL)
  338. dns_name_clone(&name, bad);
  339. return (ISC_FALSE);
  340. }
  341. return (ISC_TRUE);
  342. }
  343. static inline int
  344. casecompare_soa(ARGS_COMPARE) {
  345. return (compare_soa(rdata1, rdata2));
  346. }
  347. #endif /* RDATA_GENERIC_SOA_6_C */