/contrib/bind9/lib/export/samples/sample-request.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 263 lines · 200 code · 39 blank · 24 comment · 39 complexity · bcb4c3ea93ca58daaa7071fe47fd1b7e MD5 · raw file

  1. /*
  2. * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  9. * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  10. * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  11. * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  12. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  13. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  14. * PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. /* $Id: sample-request.c,v 1.5 2009/09/29 15:06:07 fdupont Exp $ */
  17. #include <config.h>
  18. #include <sys/types.h>
  19. #include <sys/socket.h>
  20. #include <netinet/in.h>
  21. #include <arpa/inet.h>
  22. #include <unistd.h>
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <netdb.h>
  27. #include <isc/base64.h>
  28. #include <isc/buffer.h>
  29. #include <isc/lib.h>
  30. #include <isc/mem.h>
  31. #include <isc/sockaddr.h>
  32. #include <isc/util.h>
  33. #include <dns/client.h>
  34. #include <dns/fixedname.h>
  35. #include <dns/keyvalues.h>
  36. #include <dns/lib.h>
  37. #include <dns/masterdump.h>
  38. #include <dns/message.h>
  39. #include <dns/name.h>
  40. #include <dns/rdata.h>
  41. #include <dns/rdataset.h>
  42. #include <dns/rdatastruct.h>
  43. #include <dns/rdatatype.h>
  44. #include <dns/result.h>
  45. #include <dns/secalg.h>
  46. #include <dst/dst.h>
  47. static isc_mem_t *mctx;
  48. static dns_fixedname_t fixedqname;
  49. ISC_PLATFORM_NORETURN_PRE static void
  50. usage(void) ISC_PLATFORM_NORETURN_POST;
  51. static void
  52. usage(void) {
  53. fprintf(stderr, "sample-request [-t RRtype] server_address hostname\n");
  54. exit(1);
  55. }
  56. static isc_result_t
  57. make_querymessage(dns_message_t *message, const char *namestr,
  58. dns_rdatatype_t rdtype)
  59. {
  60. dns_name_t *qname = NULL, *qname0;
  61. dns_rdataset_t *qrdataset = NULL;
  62. isc_result_t result;
  63. isc_buffer_t b;
  64. size_t namelen;
  65. /* Construct qname */
  66. namelen = strlen(namestr);
  67. isc_buffer_init(&b, namestr, namelen);
  68. isc_buffer_add(&b, namelen);
  69. dns_fixedname_init(&fixedqname);
  70. qname0 = dns_fixedname_name(&fixedqname);
  71. result = dns_name_fromtext(qname0, &b, dns_rootname, 0, NULL);
  72. if (result != ISC_R_SUCCESS) {
  73. fprintf(stderr, "failed to convert qname: %d\n", result);
  74. return (result);
  75. }
  76. /* Construct query message */
  77. message->opcode = dns_opcode_query;
  78. message->rdclass = dns_rdataclass_in;
  79. result = dns_message_gettempname(message, &qname);
  80. if (result != ISC_R_SUCCESS)
  81. goto cleanup;
  82. result = dns_message_gettemprdataset(message, &qrdataset);
  83. if (result != ISC_R_SUCCESS)
  84. goto cleanup;
  85. dns_name_init(qname, NULL);
  86. dns_name_clone(qname0, qname);
  87. dns_rdataset_init(qrdataset);
  88. dns_rdataset_makequestion(qrdataset, message->rdclass, rdtype);
  89. ISC_LIST_APPEND(qname->list, qrdataset, link);
  90. dns_message_addname(message, qname, DNS_SECTION_QUESTION);
  91. return (ISC_R_SUCCESS);
  92. cleanup:
  93. if (qname != NULL)
  94. dns_message_puttempname(message, &qname);
  95. if (qrdataset != NULL)
  96. dns_message_puttemprdataset(message, &qrdataset);
  97. if (message != NULL)
  98. dns_message_destroy(&message);
  99. return (result);
  100. }
  101. static void
  102. print_section(dns_message_t *message, int section, isc_buffer_t *buf) {
  103. isc_result_t result;
  104. isc_region_t r;
  105. result = dns_message_sectiontotext(message, section,
  106. &dns_master_style_full, 0, buf);
  107. if (result != ISC_R_SUCCESS)
  108. goto fail;
  109. isc_buffer_usedregion(buf, &r);
  110. printf("%.*s", (int)r.length, (char *)r.base);
  111. return;
  112. fail:
  113. fprintf(stderr, "failed to convert a section\n");
  114. }
  115. int
  116. main(int argc, char *argv[]) {
  117. int ch, i, gai_error;
  118. struct addrinfo hints, *res;
  119. isc_textregion_t tr;
  120. dns_client_t *client = NULL;
  121. isc_result_t result;
  122. isc_sockaddr_t sa;
  123. dns_message_t *qmessage, *rmessage;
  124. dns_rdatatype_t type = dns_rdatatype_a;
  125. isc_buffer_t *outputbuf;
  126. while ((ch = getopt(argc, argv, "t:")) != -1) {
  127. switch (ch) {
  128. case 't':
  129. tr.base = optarg;
  130. tr.length = strlen(optarg);
  131. result = dns_rdatatype_fromtext(&type, &tr);
  132. if (result != ISC_R_SUCCESS) {
  133. fprintf(stderr,
  134. "invalid RRtype: %s\n", optarg);
  135. exit(1);
  136. }
  137. break;
  138. default:
  139. usage();
  140. }
  141. }
  142. argc -= optind;
  143. argv += optind;
  144. if (argc < 2)
  145. usage();
  146. isc_lib_register();
  147. result = dns_lib_init();
  148. if (result != ISC_R_SUCCESS) {
  149. fprintf(stderr, "dns_lib_init failed: %d\n", result);
  150. exit(1);
  151. }
  152. result = dns_client_create(&client, 0);
  153. if (result != ISC_R_SUCCESS) {
  154. fprintf(stderr, "dns_client_create failed: %d\n", result);
  155. exit(1);
  156. }
  157. /* Prepare message structures */
  158. mctx = NULL;
  159. qmessage = NULL;
  160. rmessage = NULL;
  161. result = isc_mem_create(0, 0, &mctx);
  162. if (result != ISC_R_SUCCESS) {
  163. fprintf(stderr, "failed to create a memory context\n");
  164. exit(1);
  165. }
  166. result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &qmessage);
  167. if (result == ISC_R_SUCCESS) {
  168. result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE,
  169. &rmessage);
  170. }
  171. if (result != ISC_R_SUCCESS) {
  172. fprintf(stderr, "failed to create messages\n");
  173. exit(1);
  174. }
  175. /* Initialize the nameserver address */
  176. memset(&hints, 0, sizeof(hints));
  177. hints.ai_family = AF_UNSPEC;
  178. hints.ai_socktype = SOCK_DGRAM;
  179. hints.ai_protocol = IPPROTO_UDP;
  180. hints.ai_flags = AI_NUMERICHOST;
  181. gai_error = getaddrinfo(argv[0], "53", &hints, &res);
  182. if (gai_error != 0) {
  183. fprintf(stderr, "getaddrinfo failed: %s\n",
  184. gai_strerror(gai_error));
  185. exit(1);
  186. }
  187. INSIST(res->ai_addrlen <= sizeof(sa.type));
  188. memcpy(&sa.type, res->ai_addr, res->ai_addrlen);
  189. freeaddrinfo(res);
  190. sa.length = res->ai_addrlen;
  191. ISC_LINK_INIT(&sa, link);
  192. /* Construct qname */
  193. result = make_querymessage(qmessage, argv[1], type);
  194. if (result != ISC_R_SUCCESS) {
  195. fprintf(stderr, "failed to create a query\n");
  196. exit(1);
  197. }
  198. /* Send request and wait for a response */
  199. result = dns_client_request(client, qmessage, rmessage, &sa, 0, 0,
  200. NULL, 60, 0, 3);
  201. if (result != ISC_R_SUCCESS) {
  202. fprintf(stderr, "failed to get a response: %s\n",
  203. dns_result_totext(result));
  204. }
  205. /* Dump the response */
  206. outputbuf = NULL;
  207. result = isc_buffer_allocate(mctx, &outputbuf, 65535);
  208. if (result != ISC_R_SUCCESS) {
  209. fprintf(stderr, "failed to allocate a result buffer\n");
  210. exit(1);
  211. }
  212. for (i = 0; i < DNS_SECTION_MAX; i++) {
  213. print_section(rmessage, i, outputbuf);
  214. isc_buffer_clear(outputbuf);
  215. }
  216. isc_buffer_free(&outputbuf);
  217. /* Cleanup */
  218. dns_message_destroy(&qmessage);
  219. dns_message_destroy(&rmessage);
  220. isc_mem_destroy(&mctx);
  221. dns_client_destroy(&client);
  222. dns_lib_shutdown();
  223. exit(0);
  224. }