aboutsummaryrefslogtreecommitdiffstats
path: root/wlantest/process.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2010-11-23 12:27:28 (GMT)
committerJouni Malinen <j@w1.fi>2010-11-23 12:27:28 (GMT)
commita912dd16c546de57f0b7b676abdd6f2bf97be09a (patch)
tree41121090873e892198463ac40e73f90457408f1d /wlantest/process.c
parent107ad4e3233c44dba57b3de335af7f53c7f56c60 (diff)
downloadhostap-a912dd16c546de57f0b7b676abdd6f2bf97be09a.zip
hostap-a912dd16c546de57f0b7b676abdd6f2bf97be09a.tar.gz
hostap-a912dd16c546de57f0b7b676abdd6f2bf97be09a.tar.bz2
wlantest: Implement IEEE 802.11 duplicate detection
This cleans up debug logs by avoiding incorrect entries on TKIP/CCMP replays and some state changes.
Diffstat (limited to 'wlantest/process.c')
-rw-r--r--wlantest/process.c89
1 files changed, 88 insertions, 1 deletions
diff --git a/wlantest/process.c b/wlantest/process.c
index 6083390..7ca77b2 100644
--- a/wlantest/process.c
+++ b/wlantest/process.c
@@ -21,6 +21,85 @@
#include "wlantest.h"
+static int rx_duplicate(struct wlantest *wt, const struct ieee80211_hdr *hdr,
+ size_t len)
+{
+ u16 fc;
+ int tid = 16;
+ const u8 *sta_addr, *bssid;
+ struct wlantest_bss *bss;
+ struct wlantest_sta *sta;
+ int to_ap;
+ le16 *seq_ctrl;
+
+ if (hdr->addr1[0] & 0x01)
+ return 0; /* Ignore group addressed frames */
+
+ fc = le_to_host16(hdr->frame_control);
+ if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) {
+ bssid = hdr->addr3;
+ if (os_memcmp(bssid, hdr->addr2, ETH_ALEN) == 0) {
+ sta_addr = hdr->addr1;
+ to_ap = 0;
+ } else {
+ if (os_memcmp(bssid, hdr->addr1, ETH_ALEN) != 0)
+ return 0; /* Unsupported STA-to-STA frame */
+ sta_addr = hdr->addr2;
+ to_ap = 1;
+ }
+ } else {
+ switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
+ case 0:
+ return 0; /* IBSS not supported */
+ case WLAN_FC_FROMDS:
+ sta_addr = hdr->addr1;
+ bssid = hdr->addr2;
+ to_ap = 0;
+ break;
+ case WLAN_FC_TODS:
+ sta_addr = hdr->addr2;
+ bssid = hdr->addr1;
+ to_ap = 1;
+ break;
+ case WLAN_FC_TODS | WLAN_FC_FROMDS:
+ return 0; /* WDS not supported */
+ default:
+ return 0;
+ }
+
+ if ((WLAN_FC_GET_STYPE(fc) & 0x08) && len >= 26) {
+ const u8 *qos = ((const u8 *) hdr) + 24;
+ tid = qos[0] & 0x0f;
+ }
+ }
+
+ bss = bss_find(wt, bssid);
+ if (bss == NULL)
+ return 0;
+ sta = sta_find(bss, sta_addr);
+ if (sta == NULL)
+ return 0;
+
+ if (to_ap)
+ seq_ctrl = &sta->seq_ctrl_to_ap[tid];
+ else
+ seq_ctrl = &sta->seq_ctrl_to_sta[tid];
+
+ if ((fc & WLAN_FC_RETRY) && hdr->seq_ctrl == *seq_ctrl) {
+ u16 s = le_to_host16(hdr->seq_ctrl);
+ wpa_printf(MSG_MSGDUMP, "Ignore duplicated frame (seq=%u "
+ "frag=%u A1=" MACSTR " A2=" MACSTR ")",
+ WLAN_GET_SEQ_SEQ(s), WLAN_GET_SEQ_FRAG(s),
+ MAC2STR(hdr->addr1), MAC2STR(hdr->addr2));
+ return 1;
+ }
+
+ *seq_ctrl = hdr->seq_ctrl;
+
+ return 0;
+}
+
+
static void rx_frame(struct wlantest *wt, const u8 *data, size_t len)
{
const struct ieee80211_hdr *hdr;
@@ -40,14 +119,22 @@ static void rx_frame(struct wlantest *wt, const u8 *data, size_t len)
switch (WLAN_FC_GET_TYPE(fc)) {
case WLAN_FC_TYPE_MGMT:
+ if (len < 24)
+ break;
+ if (rx_duplicate(wt, hdr, len))
+ break;
rx_mgmt(wt, data, len);
break;
case WLAN_FC_TYPE_CTRL:
if (len < 10)
- return;
+ break;
wt->rx_ctrl++;
break;
case WLAN_FC_TYPE_DATA:
+ if (len < 24)
+ break;
+ if (rx_duplicate(wt, hdr, len))
+ break;
rx_data(wt, data, len);
break;
default: