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