readpcap.c 3.2 KB

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