recv-pcap.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * ZMap Copyright 2013 Regents of the University of Michigan
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy
  6. * of the License at http://www.apache.org/licenses/LICENSE-2.0
  7. */
  8. #include "recv.h"
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <unistd.h>
  13. #include <pthread.h>
  14. #include <assert.h>
  15. #include "../lib/includes.h"
  16. #include "../lib/logger.h"
  17. #include <pcap.h>
  18. #include <pcap/pcap.h>
  19. #include "recv-internal.h"
  20. #include "state.h"
  21. #include "probe_modules/probe_modules.h"
  22. #define PCAP_PROMISC 1
  23. #define PCAP_TIMEOUT 1000
  24. static pcap_t *pc = NULL;
  25. void packet_cb(u_char __attribute__((__unused__)) *user,
  26. const struct pcap_pkthdr *p, const u_char *bytes)
  27. {
  28. if (!p) {
  29. return;
  30. }
  31. if (zrecv.success_unique >= zconf.max_results) {
  32. // Libpcap can process multiple packets per pcap_dispatch;
  33. // we need to throw out results once we've
  34. // gotten our --max-results worth.
  35. return;
  36. }
  37. // length of entire packet captured by libpcap
  38. uint32_t buflen = (uint32_t) p->caplen;
  39. handle_packet(buflen, bytes);
  40. }
  41. void recv_init()
  42. {
  43. char bpftmp[1024];
  44. char errbuf[PCAP_ERRBUF_SIZE];
  45. pc = pcap_open_live(zconf.iface, zconf.probe_module->pcap_snaplen,
  46. PCAP_PROMISC, PCAP_TIMEOUT, errbuf);
  47. if (pc == NULL) {
  48. log_fatal("recv", "could not open device %s: %s",
  49. zconf.iface, errbuf);
  50. }
  51. struct bpf_program bpf;
  52. // PROBLEM: packets not always get answered by the same host (eg: Client -> GW -> target -> DNS -> Client)
  53. // so we can not use MAC filter.
  54. /*
  55. snprintf(bpftmp, sizeof(bpftmp)-1, "ether src %02x:%02x:%02x:%02x:%02x:%02x and (%s)",
  56. zconf.gw_mac[0], zconf.gw_mac[1], zconf.gw_mac[2],
  57. zconf.gw_mac[3], zconf.gw_mac[4], zconf.gw_mac[5],
  58. zconf.probe_module->pcap_filter);
  59. */
  60. snprintf(bpftmp, sizeof(bpftmp)-1, "%s",
  61. zconf.probe_module->pcap_filter);
  62. if (pcap_compile(pc, &bpf, bpftmp, 1, 0) < 0) {
  63. log_fatal("recv", "couldn't compile filter");
  64. }
  65. if (pcap_setfilter(pc, &bpf) < 0) {
  66. log_fatal("recv", "couldn't install filter");
  67. }
  68. // set pcap_dispatch to not hang if it never receives any packets
  69. // this could occur if you ever scan a small number of hosts as
  70. // documented in issue #74.
  71. if (pcap_setnonblock (pc, 1, errbuf) == -1) {
  72. log_fatal("recv", "pcap_setnonblock error:%s", errbuf);
  73. }
  74. }
  75. void recv_packets()
  76. {
  77. int ret = pcap_dispatch(pc, -1, packet_cb, NULL);
  78. if (ret == -1) {
  79. log_fatal("recv", "pcap_dispatch error");
  80. } else if (ret == 0) {
  81. //log_debug("recv", "before sleep");
  82. usleep(1000);
  83. //log_debug("recv", "after sleep");
  84. }
  85. }
  86. void recv_cleanup()
  87. {
  88. pcap_close(pc);
  89. pc = NULL;
  90. }
  91. int recv_update_stats(void)
  92. {
  93. if (!pc) {
  94. return EXIT_FAILURE;
  95. }
  96. struct pcap_stat pcst;
  97. if (pcap_stats(pc, &pcst)) {
  98. log_error("recv", "unable to retrieve pcap statistics: %s",
  99. pcap_geterr(pc));
  100. return EXIT_FAILURE;
  101. } else {
  102. zrecv.pcap_recv = pcst.ps_recv;
  103. zrecv.pcap_drop = pcst.ps_drop;
  104. zrecv.pcap_ifdrop = pcst.ps_ifdrop;
  105. }
  106. return EXIT_SUCCESS;
  107. }