readpcap.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * PCAP capture file reader
  3. * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * Alternatively, this software may be distributed under the terms of BSD
  10. * license.
  11. *
  12. * See README and COPYING for more details.
  13. */
  14. #include "utils/includes.h"
  15. #include <pcap.h>
  16. #include "utils/common.h"
  17. #include "wlantest.h"
  18. int read_cap_file(struct wlantest *wt, const char *fname)
  19. {
  20. char errbuf[PCAP_ERRBUF_SIZE];
  21. pcap_t *pcap;
  22. unsigned int count = 0;
  23. struct pcap_pkthdr *hdr;
  24. const u_char *data;
  25. int res;
  26. int dlt;
  27. pcap = pcap_open_offline(fname, errbuf);
  28. if (pcap == NULL) {
  29. wpa_printf(MSG_ERROR, "Failed to read pcap file '%s': %s",
  30. fname, errbuf);
  31. return -1;
  32. }
  33. dlt = pcap_datalink(pcap);
  34. if (dlt != DLT_IEEE802_11_RADIO && dlt != DLT_PRISM_HEADER &&
  35. dlt != DLT_IEEE802_11) {
  36. wpa_printf(MSG_ERROR, "Unsupported pcap datalink type: %d",
  37. dlt);
  38. pcap_close(pcap);
  39. return -1;
  40. }
  41. wpa_printf(MSG_DEBUG, "pcap datalink type: %d", dlt);
  42. for (;;) {
  43. res = pcap_next_ex(pcap, &hdr, &data);
  44. if (res == -2)
  45. break; /* No more packets */
  46. if (res == -1) {
  47. wpa_printf(MSG_INFO, "pcap_next_ex failure: %s",
  48. pcap_geterr(pcap));
  49. break;
  50. }
  51. if (res != 1) {
  52. wpa_printf(MSG_INFO, "Unexpected pcap_next_ex return "
  53. "value %d", res);
  54. break;
  55. }
  56. /* Packet was read without problems */
  57. wpa_printf(MSG_EXCESSIVE, "pcap hdr: ts=%d.%06d "
  58. "len=%u/%u",
  59. (int) hdr->ts.tv_sec, (int) hdr->ts.tv_usec,
  60. hdr->caplen, hdr->len);
  61. if (wt->write_pcap_dumper) {
  62. wt->write_pcap_time = hdr->ts;
  63. pcap_dump(wt->write_pcap_dumper, hdr, data);
  64. }
  65. if (hdr->caplen < hdr->len) {
  66. wpa_printf(MSG_DEBUG, "pcap: Dropped incomplete frame "
  67. "(%u/%u captured)",
  68. hdr->caplen, hdr->len);
  69. continue;
  70. }
  71. count++;
  72. switch (dlt) {
  73. case DLT_IEEE802_11_RADIO:
  74. wlantest_process(wt, data, hdr->caplen);
  75. break;
  76. case DLT_PRISM_HEADER:
  77. wlantest_process_prism(wt, data, hdr->caplen);
  78. break;
  79. case DLT_IEEE802_11:
  80. wlantest_process_80211(wt, data, hdr->caplen);
  81. }
  82. }
  83. pcap_close(pcap);
  84. wpa_printf(MSG_DEBUG, "Read %s: %u packets", fname, count);
  85. return 0;
  86. }
  87. int read_wired_cap_file(struct wlantest *wt, const char *fname)
  88. {
  89. char errbuf[PCAP_ERRBUF_SIZE];
  90. pcap_t *pcap;
  91. unsigned int count = 0;
  92. struct pcap_pkthdr *hdr;
  93. const u_char *data;
  94. int res;
  95. pcap = pcap_open_offline(fname, errbuf);
  96. if (pcap == NULL) {
  97. wpa_printf(MSG_ERROR, "Failed to read pcap file '%s': %s",
  98. fname, errbuf);
  99. return -1;
  100. }
  101. for (;;) {
  102. res = pcap_next_ex(pcap, &hdr, &data);
  103. if (res == -2)
  104. break; /* No more packets */
  105. if (res == -1) {
  106. wpa_printf(MSG_INFO, "pcap_next_ex failure: %s",
  107. pcap_geterr(pcap));
  108. break;
  109. }
  110. if (res != 1) {
  111. wpa_printf(MSG_INFO, "Unexpected pcap_next_ex return "
  112. "value %d", res);
  113. break;
  114. }
  115. /* Packet was read without problems */
  116. wpa_printf(MSG_EXCESSIVE, "pcap hdr: ts=%d.%06d "
  117. "len=%u/%u",
  118. (int) hdr->ts.tv_sec, (int) hdr->ts.tv_usec,
  119. hdr->caplen, hdr->len);
  120. if (hdr->caplen < hdr->len) {
  121. wpa_printf(MSG_DEBUG, "pcap: Dropped incomplete frame "
  122. "(%u/%u captured)",
  123. hdr->caplen, hdr->len);
  124. continue;
  125. }
  126. count++;
  127. wlantest_process_wired(wt, data, hdr->caplen);
  128. }
  129. pcap_close(pcap);
  130. wpa_printf(MSG_DEBUG, "Read %s: %u packets", fname, count);
  131. return 0;
  132. }