]> git.ipfire.org Git - thirdparty/hostap.git/blame - wlantest/readpcap.c
wlantest: Add support for writing pcapng files
[thirdparty/hostap.git] / wlantest / readpcap.c
CommitLineData
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
0321bcdf
JM
16static void write_pcap_with_radiotap(struct wlantest *wt,
17 const u8 *data, size_t data_len)
18{
19 struct pcap_pkthdr h;
20 u8 rtap[] = {
21 0x00 /* rev */,
22 0x00 /* pad */,
23 0x0a, 0x00, /* header len */
24 0x02, 0x00, 0x00, 0x00, /* present flags */
25 0x00, /* flags */
26 0x00 /* pad */
27 };
28 u8 *buf;
29 size_t len;
30
31 if (wt->assume_fcs)
32 rtap[8] |= 0x10;
33
34 os_memset(&h, 0, sizeof(h));
35 h.ts = wt->write_pcap_time;
36 len = sizeof(rtap) + data_len;
37 buf = os_malloc(len);
38 if (buf == NULL)
39 return;
40 os_memcpy(buf, rtap, sizeof(rtap));
41 os_memcpy(buf + sizeof(rtap), data, data_len);
42 h.caplen = len;
43 h.len = len;
44 pcap_dump(wt->write_pcap_dumper, &h, buf);
45 os_free(buf);
46}
47
48
a149fcc7
JM
49int read_cap_file(struct wlantest *wt, const char *fname)
50{
51 char errbuf[PCAP_ERRBUF_SIZE];
52 pcap_t *pcap;
53 unsigned int count = 0;
54 struct pcap_pkthdr *hdr;
55 const u_char *data;
56 int res;
350132be 57 int dlt;
a149fcc7
JM
58
59 pcap = pcap_open_offline(fname, errbuf);
60 if (pcap == NULL) {
61 wpa_printf(MSG_ERROR, "Failed to read pcap file '%s': %s",
62 fname, errbuf);
63 return -1;
64 }
350132be 65 dlt = pcap_datalink(pcap);
0f3e4f2a
JM
66 if (dlt != DLT_IEEE802_11_RADIO && dlt != DLT_PRISM_HEADER &&
67 dlt != DLT_IEEE802_11) {
350132be
JM
68 wpa_printf(MSG_ERROR, "Unsupported pcap datalink type: %d",
69 dlt);
70 pcap_close(pcap);
71 return -1;
72 }
73 wpa_printf(MSG_DEBUG, "pcap datalink type: %d", dlt);
a149fcc7
JM
74
75 for (;;) {
ba2beacc
JM
76 clear_notes(wt);
77 os_free(wt->decrypted);
78 wt->decrypted = NULL;
79
a149fcc7
JM
80 res = pcap_next_ex(pcap, &hdr, &data);
81 if (res == -2)
82 break; /* No more packets */
83 if (res == -1) {
84 wpa_printf(MSG_INFO, "pcap_next_ex failure: %s",
85 pcap_geterr(pcap));
86 break;
87 }
88 if (res != 1) {
89 wpa_printf(MSG_INFO, "Unexpected pcap_next_ex return "
90 "value %d", res);
91 break;
92 }
93
94 /* Packet was read without problems */
95 wpa_printf(MSG_EXCESSIVE, "pcap hdr: ts=%d.%06d "
96 "len=%u/%u",
97 (int) hdr->ts.tv_sec, (int) hdr->ts.tv_usec,
98 hdr->caplen, hdr->len);
64f45d07
JM
99 if (wt->write_pcap_dumper) {
100 wt->write_pcap_time = hdr->ts;
0321bcdf
JM
101 if (dlt == DLT_IEEE802_11)
102 write_pcap_with_radiotap(wt, data, hdr->caplen);
103 else
104 pcap_dump(wt->write_pcap_dumper, hdr, data);
64f45d07 105 }
a149fcc7 106 if (hdr->caplen < hdr->len) {
ba2beacc
JM
107 add_note(wt, MSG_DEBUG, "pcap: Dropped incomplete "
108 "frame (%u/%u captured)",
109 hdr->caplen, hdr->len);
110 write_pcapng_write_read(wt, dlt, hdr, data);
a149fcc7
JM
111 continue;
112 }
113 count++;
350132be
JM
114 switch (dlt) {
115 case DLT_IEEE802_11_RADIO:
116 wlantest_process(wt, data, hdr->caplen);
117 break;
118 case DLT_PRISM_HEADER:
119 wlantest_process_prism(wt, data, hdr->caplen);
120 break;
0f3e4f2a
JM
121 case DLT_IEEE802_11:
122 wlantest_process_80211(wt, data, hdr->caplen);
ba2beacc 123 break;
350132be 124 }
ba2beacc 125 write_pcapng_write_read(wt, dlt, hdr, data);
a149fcc7
JM
126 }
127
128 pcap_close(pcap);
129
130 wpa_printf(MSG_DEBUG, "Read %s: %u packets", fname, count);
131
132 return 0;
133}
3215df77
JM
134
135
136int read_wired_cap_file(struct wlantest *wt, const char *fname)
137{
138 char errbuf[PCAP_ERRBUF_SIZE];
139 pcap_t *pcap;
140 unsigned int count = 0;
141 struct pcap_pkthdr *hdr;
142 const u_char *data;
143 int res;
144
145 pcap = pcap_open_offline(fname, errbuf);
146 if (pcap == NULL) {
147 wpa_printf(MSG_ERROR, "Failed to read pcap file '%s': %s",
148 fname, errbuf);
149 return -1;
150 }
151
152 for (;;) {
153 res = pcap_next_ex(pcap, &hdr, &data);
154 if (res == -2)
155 break; /* No more packets */
156 if (res == -1) {
157 wpa_printf(MSG_INFO, "pcap_next_ex failure: %s",
158 pcap_geterr(pcap));
159 break;
160 }
161 if (res != 1) {
162 wpa_printf(MSG_INFO, "Unexpected pcap_next_ex return "
163 "value %d", res);
164 break;
165 }
166
167 /* Packet was read without problems */
168 wpa_printf(MSG_EXCESSIVE, "pcap hdr: ts=%d.%06d "
169 "len=%u/%u",
170 (int) hdr->ts.tv_sec, (int) hdr->ts.tv_usec,
171 hdr->caplen, hdr->len);
172 if (hdr->caplen < hdr->len) {
173 wpa_printf(MSG_DEBUG, "pcap: Dropped incomplete frame "
174 "(%u/%u captured)",
175 hdr->caplen, hdr->len);
176 continue;
177 }
178 count++;
179 wlantest_process_wired(wt, data, hdr->caplen);
180 }
181
182 pcap_close(pcap);
183
184 wpa_printf(MSG_DEBUG, "Read %s: %u packets", fname, count);
185
186 return 0;
187}