diff --git a/wlantest/process.c b/wlantest/process.c index 7ca77b20d..78908927e 100644 --- a/wlantest/process.c +++ b/wlantest/process.c @@ -224,3 +224,41 @@ void wlantest_process(struct wlantest *wt, const u8 *data, size_t len) else tx_status(wt, frame, frame_len, !failed); } + + +void wlantest_process_prism(struct wlantest *wt, const u8 *data, size_t len) +{ + int fcs = 0; + const u8 *frame, *fcspos; + size_t frame_len; + u32 hdrlen; + + wpa_hexdump(MSG_EXCESSIVE, "Process data", data, len); + + if (len < 8) + return; + hdrlen = WPA_GET_LE32(data + 4); + + if (len < hdrlen) { + wpa_printf(MSG_INFO, "Too short frame to include prism " + "header"); + return; + } + + frame = data + hdrlen; + frame_len = len - hdrlen; + fcs = 1; + + if (fcs && frame_len >= 4) { + frame_len -= 4; + fcspos = frame + frame_len; + if (check_fcs(frame, frame_len, fcspos) < 0) { + wpa_printf(MSG_EXCESSIVE, "Drop RX frame with invalid " + "FCS"); + wt->fcs_error++; + return; + } + } + + rx_frame(wt, frame, frame_len); +} diff --git a/wlantest/readpcap.c b/wlantest/readpcap.c index bd93d7b5c..ecb5ae22a 100644 --- a/wlantest/readpcap.c +++ b/wlantest/readpcap.c @@ -27,6 +27,7 @@ int read_cap_file(struct wlantest *wt, const char *fname) struct pcap_pkthdr *hdr; const u_char *data; int res; + int dlt; pcap = pcap_open_offline(fname, errbuf); if (pcap == NULL) { @@ -34,6 +35,14 @@ int read_cap_file(struct wlantest *wt, const char *fname) fname, errbuf); return -1; } + dlt = pcap_datalink(pcap); + if (dlt != DLT_IEEE802_11_RADIO && dlt != DLT_PRISM_HEADER) { + wpa_printf(MSG_ERROR, "Unsupported pcap datalink type: %d", + dlt); + pcap_close(pcap); + return -1; + } + wpa_printf(MSG_DEBUG, "pcap datalink type: %d", dlt); for (;;) { res = pcap_next_ex(pcap, &hdr, &data); @@ -66,7 +75,14 @@ int read_cap_file(struct wlantest *wt, const char *fname) continue; } count++; - wlantest_process(wt, data, hdr->caplen); + switch (dlt) { + case DLT_IEEE802_11_RADIO: + wlantest_process(wt, data, hdr->caplen); + break; + case DLT_PRISM_HEADER: + wlantest_process_prism(wt, data, hdr->caplen); + break; + } } pcap_close(pcap); diff --git a/wlantest/wlantest.h b/wlantest/wlantest.h index 6bb8e1edb..81f473148 100644 --- a/wlantest/wlantest.h +++ b/wlantest/wlantest.h @@ -154,6 +154,7 @@ void write_pcap_captured(struct wlantest *wt, const u8 *buf, size_t len); void write_pcap_decrypted(struct wlantest *wt, const u8 *buf1, size_t len1, const u8 *buf2, size_t len2); void wlantest_process(struct wlantest *wt, const u8 *data, size_t len); +void wlantest_process_prism(struct wlantest *wt, const u8 *data, size_t len); void wlantest_process_wired(struct wlantest *wt, const u8 *data, size_t len); u32 crc32(const u8 *frame, size_t frame_len); int monitor_init(struct wlantest *wt, const char *ifname);