senddnsquery-libnet.c 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "udpcksum.h"
  2. #include <libnet.h>
  3. /*
  4. * Build a DNS A query for "a.root-servers.net" and write it to
  5. * the raw socket.
  6. */
  7. /* include open_output_libnet */
  8. static libnet_t *l; /* libnet descriptor */
  9. void
  10. open_output(void)
  11. {
  12. char errbuf[LIBNET_ERRBUF_SIZE];
  13. /* Initialize libnet with an IPv4 raw socket */
  14. l = libnet_init(LIBNET_RAW4, NULL, errbuf);
  15. if (l == NULL) {
  16. err_quit("Can't initialize libnet: %s", errbuf);
  17. }
  18. }
  19. /* end open_output_libnet */
  20. /* include send_dns_query_libnet */
  21. void
  22. send_dns_query(void)
  23. {
  24. char qbuf[24], *ptr;
  25. u_int16_t one;
  26. int packet_size = LIBNET_UDP_H + LIBNET_DNSV4_H + 24;
  27. static libnet_ptag_t ip_tag, udp_tag, dns_tag;
  28. /* build query portion of DNS packet */
  29. ptr = qbuf;
  30. memcpy(ptr, "\001a\014root-servers\003net\000", 20);
  31. ptr += 20;
  32. one = htons(1);
  33. memcpy(ptr, &one, 2); /* query type = A */
  34. ptr += 2;
  35. memcpy(ptr, &one, 2); /* query class = 1 (IP addr) */
  36. /* build DNS packet */
  37. dns_tag = libnet_build_dnsv4(
  38. 1234 /* identification */,
  39. 0x0100 /* flags: recursion desired */,
  40. 1 /* # questions */, 0 /* # answer RRs */,
  41. 0 /* # authority RRs */, 0 /* # additional RRs */,
  42. qbuf /* query */, 24 /* length of query */, l, dns_tag);
  43. /* build UDP header */
  44. udp_tag = libnet_build_udp(
  45. ((struct sockaddr_in *) local)->sin_port /* source port */,
  46. ((struct sockaddr_in *) dest)->sin_port /* dest port */,
  47. packet_size /* length */, 0 /* checksum */,
  48. NULL /* payload */, 0 /* payload length */, l, udp_tag);
  49. /* Since we specified the checksum as 0, libnet will automatically */
  50. /* calculate the UDP checksum. Turn it off if the user doesn't want it. */
  51. if (zerosum)
  52. if (libnet_toggle_checksum(l, udp_tag, LIBNET_OFF) < 0)
  53. err_quit("turning off checksums: %s\n", libnet_geterror(l));
  54. /* build IP header */
  55. /* *INDENT-OFF* */
  56. ip_tag = libnet_build_ipv4(packet_size + LIBNET_IPV4_H /* len */,
  57. 0 /* tos */, 0 /* IP ID */, 0 /* fragment */,
  58. TTL_OUT /* ttl */, IPPROTO_UDP /* protocol */,
  59. 0 /* checksum */,
  60. ((struct sockaddr_in *) local)->sin_addr.s_addr /* source */,
  61. ((struct sockaddr_in *) dest)->sin_addr.s_addr /* dest */,
  62. NULL /* payload */, 0 /* payload length */, l, ip_tag);
  63. /* *INDENT-ON* */
  64. if (libnet_write(l) < 0) {
  65. err_quit("libnet_write: %s\n", libnet_geterror(l));
  66. }
  67. if (verbose)
  68. printf("sent: %d bytes of data\n", packet_size);
  69. }
  70. /* end send_dns_query_libnet */