aboutsummaryrefslogtreecommitdiffstats
path: root/wlantest
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-08-09 20:10:01 (GMT)
committerJouni Malinen <j@w1.fi>2012-08-09 20:18:32 (GMT)
commitdcf10b4502bd7f07d0d5132b62112f3850c24fbb (patch)
treea96612fb3badad072aba2487ac1d5fcc90f5ec4e /wlantest
parent3aed10f3b7f643f288f6aa1c5aef223c5c679b9e (diff)
downloadhostap-aosp-jb.zip
hostap-aosp-jb.tar.gz
hostap-aosp-jb.tar.bz2
AOSP: These files have been removed from AOSPaosp-jb
Diffstat (limited to 'wlantest')
-rw-r--r--wlantest/Makefile111
-rw-r--r--wlantest/bss.c297
-rw-r--r--wlantest/ccmp.c349
-rw-r--r--wlantest/crc32.c84
-rw-r--r--wlantest/ctrl.c1364
-rw-r--r--wlantest/inject.c375
-rw-r--r--wlantest/monitor.c144
-rw-r--r--wlantest/process.c381
-rw-r--r--wlantest/readpcap.c144
-rw-r--r--wlantest/rx_data.c529
-rw-r--r--wlantest/rx_eapol.c1034
-rw-r--r--wlantest/rx_ip.c157
-rw-r--r--wlantest/rx_mgmt.c1169
-rw-r--r--wlantest/rx_tdls.c568
-rw-r--r--wlantest/sta.c183
-rw-r--r--wlantest/tkip.c381
-rw-r--r--wlantest/wep.c103
-rw-r--r--wlantest/wired.c288
-rw-r--r--wlantest/wlantest.c304
-rw-r--r--wlantest/wlantest.h247
-rw-r--r--wlantest/wlantest_cli.c1714
-rw-r--r--wlantest/wlantest_ctrl.h166
-rw-r--r--wlantest/writepcap.c97
23 files changed, 0 insertions, 10189 deletions
diff --git a/wlantest/Makefile b/wlantest/Makefile
deleted file mode 100644
index c165ed4..0000000
--- a/wlantest/Makefile
+++ /dev/null
@@ -1,111 +0,0 @@
-ALL=wlantest wlantest_cli
-
-all: $(ALL)
-
-ifndef CC
-CC=gcc
-endif
-
-ifndef RANLIB
-RANLIB=ranlib
-endif
-
-ifndef CFLAGS
-CFLAGS = -MMD -O2 -Wall -g
-endif
-
-
-CFLAGS += -I.
-CFLAGS += -I../src
-CFLAGS += -I../src/utils
-
-
-ifndef LDO
-LDO=$(CC)
-endif
-
-Q=@
-E=echo
-ifeq ($(V), 1)
-Q=
-E=true
-endif
-
-%.o: %.c
- $(Q)$(CC) -c -o $@ $(CFLAGS) $<
- @$(E) " CC " $<
-
-
-OBJS_lib += ../src/utils/libutils.a
-OBJS_lib += ../src/crypto/libcrypto.a
-
-CFLAGS += -DCONFIG_PEERKEY
-CFLAGS += -DCONFIG_IEEE80211W
-CFLAGS += -DCONFIG_IEEE80211R
-
-OBJS += ../src/common/ieee802_11_common.o
-OBJS += ../src/common/wpa_common.o
-OBJS += ../src/radius/radius.o
-OBJS += ../src/rsn_supp/wpa_ie.o
-
-OBJS += wlantest.o
-OBJS += readpcap.o
-OBJS += writepcap.o
-OBJS += monitor.o
-OBJS += process.o
-OBJS += wired.o
-OBJS += rx_mgmt.o
-OBJS += rx_data.o
-OBJS += rx_eapol.o
-OBJS += rx_ip.o
-OBJS += rx_tdls.o
-OBJS += bss.o
-OBJS += sta.o
-OBJS += crc32.o
-OBJS += ccmp.o
-OBJS += tkip.o
-OBJS += ctrl.o
-OBJS += inject.o
-OBJS += wep.o
-
-LIBS += -lpcap
-
-
-../src/utils/libutils.a:
- $(MAKE) -C ../src/utils
-
-../src/crypto/libcrypto.a:
- $(MAKE) -C ../src/crypto
-
-
-ifneq ($(CONFIG_SOLIB), yes)
-LIBWLANTEST = libwlantest.a
-libwlantest.a: $(OBJS_lib)
- $(AR) crT libwlantest.a $(OBJS_lib)
- $(RANLIB) libwlantest.a
-
-else
-CFLAGS += -fPIC -DPIC
-LDFLAGS += -shared
-
-LIBWLANTEST = libwlantest.so
-libwlantest.so: $(OBJS_lib)
- $(LDO) $(LDFLAGS) $(OBJS_lib) -o $(LIBWLANTEST)
-
-endif
-
-
-OBJS_cli = wlantest_cli.o
-
-
-wlantest: $(OBJS) $(LIBWLANTEST)
- $(LDO) $(LDFLAGS) -o wlantest $(OBJS) -L. -lwlantest $(LIBS)
-
-wlantest_cli: $(OBJS_cli) $(LIBWLANTEST)
- $(LDO) $(LDFLAGS) -o wlantest_cli $(OBJS_cli) -L. -lwlantest
-
-clean:
- $(MAKE) -C ../src clean
- rm -f core *~ *.o *.d libwlantest.a libwlantest.so $(ALL)
-
--include $(OBJS:%.o=%.d)
diff --git a/wlantest/bss.c b/wlantest/bss.c
deleted file mode 100644
index 94f2580..0000000
--- a/wlantest/bss.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * BSS list
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/defs.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "crypto/sha1.h"
-#include "wlantest.h"
-
-
-struct wlantest_bss * bss_find(struct wlantest *wt, const u8 *bssid)
-{
- struct wlantest_bss *bss;
-
- dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
- if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
- return bss;
- }
-
- return NULL;
-}
-
-
-struct wlantest_bss * bss_get(struct wlantest *wt, const u8 *bssid)
-{
- struct wlantest_bss *bss;
-
- if (bssid[0] & 0x01)
- return NULL; /* Skip group addressed frames */
-
- bss = bss_find(wt, bssid);
- if (bss)
- return bss;
-
- bss = os_zalloc(sizeof(*bss));
- if (bss == NULL)
- return NULL;
- dl_list_init(&bss->sta);
- dl_list_init(&bss->pmk);
- dl_list_init(&bss->tdls);
- os_memcpy(bss->bssid, bssid, ETH_ALEN);
- dl_list_add(&wt->bss, &bss->list);
- wpa_printf(MSG_DEBUG, "Discovered new BSS - " MACSTR,
- MAC2STR(bss->bssid));
- return bss;
-}
-
-
-void pmk_deinit(struct wlantest_pmk *pmk)
-{
- dl_list_del(&pmk->list);
- os_free(pmk);
-}
-
-
-void tdls_deinit(struct wlantest_tdls *tdls)
-{
- dl_list_del(&tdls->list);
- os_free(tdls);
-}
-
-
-void bss_deinit(struct wlantest_bss *bss)
-{
- struct wlantest_sta *sta, *n;
- struct wlantest_pmk *pmk, *np;
- struct wlantest_tdls *tdls, *nt;
- dl_list_for_each_safe(sta, n, &bss->sta, struct wlantest_sta, list)
- sta_deinit(sta);
- dl_list_for_each_safe(pmk, np, &bss->pmk, struct wlantest_pmk, list)
- pmk_deinit(pmk);
- dl_list_for_each_safe(tdls, nt, &bss->tdls, struct wlantest_tdls, list)
- tdls_deinit(tdls);
- dl_list_del(&bss->list);
- os_free(bss);
-}
-
-
-int bss_add_pmk_from_passphrase(struct wlantest_bss *bss,
- const char *passphrase)
-{
- struct wlantest_pmk *pmk;
-
- pmk = os_zalloc(sizeof(*pmk));
- if (pmk == NULL)
- return -1;
- if (pbkdf2_sha1(passphrase, (char *) bss->ssid, bss->ssid_len, 4096,
- pmk->pmk, sizeof(pmk->pmk)) < 0) {
- os_free(pmk);
- return -1;
- }
-
- wpa_printf(MSG_INFO, "Add possible PMK for BSSID " MACSTR
- " based on passphrase '%s'",
- MAC2STR(bss->bssid), passphrase);
- wpa_hexdump(MSG_DEBUG, "Possible PMK", pmk->pmk, sizeof(pmk->pmk));
- dl_list_add(&bss->pmk, &pmk->list);
-
- return 0;
-}
-
-
-static void bss_add_pmk(struct wlantest *wt, struct wlantest_bss *bss)
-{
- struct wlantest_passphrase *p;
-
- dl_list_for_each(p, &wt->passphrase, struct wlantest_passphrase, list)
- {
- if (!is_zero_ether_addr(p->bssid) &&
- os_memcmp(p->bssid, bss->bssid, ETH_ALEN) != 0)
- continue;
- if (p->ssid_len &&
- (p->ssid_len != bss->ssid_len ||
- os_memcmp(p->ssid, bss->ssid, p->ssid_len) != 0))
- continue;
-
- if (bss_add_pmk_from_passphrase(bss, p->passphrase) < 0)
- break;
- }
-}
-
-
-void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
- struct ieee802_11_elems *elems)
-{
- struct wpa_ie_data data;
- int update = 0;
-
- if (bss->capab_info != bss->prev_capab_info)
- update = 1;
-
- if (elems->ssid == NULL || elems->ssid_len > 32) {
- wpa_printf(MSG_INFO, "Invalid or missing SSID in a Beacon "
- "frame for " MACSTR, MAC2STR(bss->bssid));
- bss->parse_error_reported = 1;
- return;
- }
-
- if (bss->ssid_len != elems->ssid_len ||
- os_memcmp(bss->ssid, elems->ssid, bss->ssid_len) != 0) {
- wpa_printf(MSG_DEBUG, "Store SSID '%s' for BSSID " MACSTR,
- wpa_ssid_txt(elems->ssid, elems->ssid_len),
- MAC2STR(bss->bssid));
- os_memcpy(bss->ssid, elems->ssid, elems->ssid_len);
- bss->ssid_len = elems->ssid_len;
- bss_add_pmk(wt, bss);
- }
-
-
- if (elems->rsn_ie == NULL) {
- if (bss->rsnie[0]) {
- wpa_printf(MSG_INFO, "BSS " MACSTR " - RSN IE removed",
- MAC2STR(bss->bssid));
- bss->rsnie[0] = 0;
- update = 1;
- }
- } else {
- if (bss->rsnie[0] == 0 ||
- os_memcmp(bss->rsnie, elems->rsn_ie - 2,
- elems->rsn_ie_len + 2) != 0) {
- wpa_printf(MSG_INFO, "BSS " MACSTR " - RSN IE "
- "stored", MAC2STR(bss->bssid));
- wpa_hexdump(MSG_DEBUG, "RSN IE", elems->rsn_ie - 2,
- elems->rsn_ie_len + 2);
- update = 1;
- }
- os_memcpy(bss->rsnie, elems->rsn_ie - 2,
- elems->rsn_ie_len + 2);
- }
-
- if (elems->wpa_ie == NULL) {
- if (bss->wpaie[0]) {
- wpa_printf(MSG_INFO, "BSS " MACSTR " - WPA IE removed",
- MAC2STR(bss->bssid));
- bss->wpaie[0] = 0;
- update = 1;
- }
- } else {
- if (bss->wpaie[0] == 0 ||
- os_memcmp(bss->wpaie, elems->wpa_ie - 2,
- elems->wpa_ie_len + 2) != 0) {
- wpa_printf(MSG_INFO, "BSS " MACSTR " - WPA IE "
- "stored", MAC2STR(bss->bssid));
- wpa_hexdump(MSG_DEBUG, "WPA IE", elems->wpa_ie - 2,
- elems->wpa_ie_len + 2);
- update = 1;
- }
- os_memcpy(bss->wpaie, elems->wpa_ie - 2,
- elems->wpa_ie_len + 2);
- }
-
- if (!update)
- return;
-
- bss->prev_capab_info = bss->capab_info;
- bss->proto = 0;
- bss->pairwise_cipher = 0;
- bss->group_cipher = 0;
- bss->key_mgmt = 0;
- bss->rsn_capab = 0;
- bss->mgmt_group_cipher = 0;
-
- if (bss->wpaie[0]) {
- if (wpa_parse_wpa_ie_wpa(bss->wpaie, 2 + bss->wpaie[1], &data)
- < 0) {
- wpa_printf(MSG_INFO, "Failed to parse WPA IE from "
- MACSTR, MAC2STR(bss->bssid));
- } else {
- bss->proto |= data.proto;
- bss->pairwise_cipher |= data.pairwise_cipher;
- bss->group_cipher |= data.group_cipher;
- bss->key_mgmt |= data.key_mgmt;
- bss->rsn_capab = data.capabilities;
- bss->mgmt_group_cipher |= data.mgmt_group_cipher;
- }
- }
-
- if (bss->rsnie[0]) {
- if (wpa_parse_wpa_ie_rsn(bss->rsnie, 2 + bss->rsnie[1], &data)
- < 0) {
- wpa_printf(MSG_INFO, "Failed to parse RSN IE from "
- MACSTR, MAC2STR(bss->bssid));
- } else {
- bss->proto |= data.proto;
- bss->pairwise_cipher |= data.pairwise_cipher;
- bss->group_cipher |= data.group_cipher;
- bss->key_mgmt |= data.key_mgmt;
- bss->rsn_capab = data.capabilities;
- bss->mgmt_group_cipher |= data.mgmt_group_cipher;
- }
- }
-
- if (!(bss->proto & WPA_PROTO_RSN) ||
- !(bss->rsn_capab & WPA_CAPABILITY_MFPC))
- bss->mgmt_group_cipher = 0;
-
- if (!bss->wpaie[0] && !bss->rsnie[0] &&
- (bss->capab_info & WLAN_CAPABILITY_PRIVACY))
- bss->group_cipher = WPA_CIPHER_WEP40;
-
- wpa_printf(MSG_INFO, "BSS " MACSTR
- " proto=%s%s%s"
- "pairwise=%s%s%s%s"
- "group=%s%s%s%s%s%s"
- "mgmt_group_cipher=%s"
- "key_mgmt=%s%s%s%s%s%s%s%s"
- "rsn_capab=%s%s%s%s%s",
- MAC2STR(bss->bssid),
- bss->proto == 0 ? "OPEN " : "",
- bss->proto & WPA_PROTO_WPA ? "WPA " : "",
- bss->proto & WPA_PROTO_RSN ? "WPA2 " : "",
- bss->pairwise_cipher == 0 ? "N/A " : "",
- bss->pairwise_cipher & WPA_CIPHER_NONE ? "NONE " : "",
- bss->pairwise_cipher & WPA_CIPHER_TKIP ? "TKIP " : "",
- bss->pairwise_cipher & WPA_CIPHER_CCMP ? "CCMP " : "",
- bss->group_cipher == 0 ? "N/A " : "",
- bss->group_cipher & WPA_CIPHER_NONE ? "NONE " : "",
- bss->group_cipher & WPA_CIPHER_WEP40 ? "WEP40 " : "",
- bss->group_cipher & WPA_CIPHER_WEP104 ? "WEP104 " : "",
- bss->group_cipher & WPA_CIPHER_TKIP ? "TKIP " : "",
- bss->group_cipher & WPA_CIPHER_CCMP ? "CCMP " : "",
- bss->mgmt_group_cipher & WPA_CIPHER_AES_128_CMAC ? "BIP " :
- "N/A ",
- bss->key_mgmt == 0 ? "N/A " : "",
- bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X ? "EAP " : "",
- bss->key_mgmt & WPA_KEY_MGMT_PSK ? "PSK " : "",
- bss->key_mgmt & WPA_KEY_MGMT_WPA_NONE ? "WPA-NONE " : "",
- bss->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X ? "FT-EAP " : "",
- bss->key_mgmt & WPA_KEY_MGMT_FT_PSK ? "FT-PSK " : "",
- bss->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256 ?
- "EAP-SHA256 " : "",
- bss->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ?
- "PSK-SHA256 " : "",
- bss->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "",
- bss->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ?
- "NO_PAIRWISE " : "",
- bss->rsn_capab & WPA_CAPABILITY_MFPR ? "MFPR " : "",
- bss->rsn_capab & WPA_CAPABILITY_MFPC ? "MFPC " : "",
- bss->rsn_capab & WPA_CAPABILITY_PEERKEY_ENABLED ?
- "PEERKEY " : "");
-}
-
-
-void bss_flush(struct wlantest *wt)
-{
- struct wlantest_bss *bss, *n;
- dl_list_for_each_safe(bss, n, &wt->bss, struct wlantest_bss, list)
- bss_deinit(bss);
-}
diff --git a/wlantest/ccmp.c b/wlantest/ccmp.c
deleted file mode 100644
index 6292ee0..0000000
--- a/wlantest/ccmp.c
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * CTR with CBC-MAC Protocol (CCMP)
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/ieee802_11_defs.h"
-#include "crypto/aes.h"
-#include "wlantest.h"
-
-
-static void ccmp_aad_nonce(const struct ieee80211_hdr *hdr, const u8 *data,
- u8 *aad, size_t *aad_len, u8 *nonce)
-{
- u16 fc, stype, seq;
- int qos = 0, addr4 = 0;
- u8 *pos;
-
- nonce[0] = 0;
-
- fc = le_to_host16(hdr->frame_control);
- stype = WLAN_FC_GET_STYPE(fc);
- if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
- (WLAN_FC_TODS | WLAN_FC_FROMDS))
- addr4 = 1;
-
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) {
- fc &= ~0x0070; /* Mask subtype bits */
- if (stype & 0x08) {
- const u8 *qc;
- qos = 1;
- fc &= ~WLAN_FC_ORDER;
- qc = (const u8 *) (hdr + 1);
- if (addr4)
- qc += ETH_ALEN;
- nonce[0] = qc[0] & 0x0f;
- }
- } else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
- nonce[0] |= 0x10; /* Management */
-
- fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
- fc |= WLAN_FC_ISWEP;
- WPA_PUT_LE16(aad, fc);
- pos = aad + 2;
- os_memcpy(pos, hdr->addr1, 3 * ETH_ALEN);
- pos += 3 * ETH_ALEN;
- seq = le_to_host16(hdr->seq_ctrl);
- seq &= ~0xfff0; /* Mask Seq#; do not modify Frag# */
- WPA_PUT_LE16(pos, seq);
- pos += 2;
-
- os_memcpy(pos, hdr + 1, addr4 * ETH_ALEN + qos * 2);
- pos += addr4 * ETH_ALEN;
- if (qos) {
- pos[0] &= ~0x70;
- if (1 /* FIX: either device has SPP A-MSDU Capab = 0 */)
- pos[0] &= ~0x80;
- pos++;
- *pos++ = 0x00;
- }
-
- *aad_len = pos - aad;
-
- os_memcpy(nonce + 1, hdr->addr2, ETH_ALEN);
- nonce[7] = data[7]; /* PN5 */
- nonce[8] = data[6]; /* PN4 */
- nonce[9] = data[5]; /* PN3 */
- nonce[10] = data[4]; /* PN2 */
- nonce[11] = data[1]; /* PN1 */
- nonce[12] = data[0]; /* PN0 */
-}
-
-
-static void xor_aes_block(u8 *dst, const u8 *src)
-{
- u32 *d = (u32 *) dst;
- u32 *s = (u32 *) src;
- *d++ ^= *s++;
- *d++ ^= *s++;
- *d++ ^= *s++;
- *d++ ^= *s++;
-}
-
-
-u8 * ccmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
- const u8 *data, size_t data_len, size_t *decrypted_len)
-{
- u8 aad[2 + 30], nonce[13];
- size_t aad_len;
- u8 b[AES_BLOCK_SIZE], x[AES_BLOCK_SIZE], a[AES_BLOCK_SIZE];
- void *aes;
- const u8 *m, *mpos, *mic;
- size_t mlen, last;
- int i;
- u8 *plain, *ppos;
- u8 t[8];
-
- if (data_len < 8 + 8)
- return NULL;
-
- plain = os_malloc(data_len + AES_BLOCK_SIZE);
- if (plain == NULL)
- return NULL;
-
- aes = aes_encrypt_init(tk, 16);
- if (aes == NULL) {
- os_free(plain);
- return NULL;
- }
-
- m = data + 8;
- mlen = data_len - 8 - 8;
- last = mlen % AES_BLOCK_SIZE;
-
- os_memset(aad, 0, sizeof(aad));
- ccmp_aad_nonce(hdr, data, &aad[2], &aad_len, nonce);
- WPA_PUT_BE16(aad, aad_len);
- wpa_hexdump(MSG_EXCESSIVE, "CCMP AAD", &aad[2], aad_len);
- wpa_hexdump(MSG_EXCESSIVE, "CCMP nonce", nonce, 13);
-
- /* CCM: M=8 L=2, Adata=1, M' = (M-2)/2 = 3, L' = L-1 = 1 */
-
- /* A_i = Flags | Nonce N | Counter i */
- a[0] = 0x01; /* Flags = L' */
- os_memcpy(&a[1], nonce, 13);
-
- /* Decryption */
-
- mic = data + data_len - 8;
- wpa_hexdump(MSG_EXCESSIVE, "CCMP U", mic, 8);
- /* U = T XOR S_0; S_0 = E(K, A_0) */
- WPA_PUT_BE16(&a[14], 0);
- aes_encrypt(aes, a, x);
- for (i = 0; i < 8; i++)
- t[i] = mic[i] ^ x[i];
- wpa_hexdump(MSG_EXCESSIVE, "CCMP T", t, 8);
-
- /* plaintext = msg XOR (S_1 | S_2 | ... | S_n) */
- ppos = plain;
- mpos = m;
- for (i = 1; i <= mlen / AES_BLOCK_SIZE; i++) {
- WPA_PUT_BE16(&a[14], i);
- /* S_i = E(K, A_i) */
- aes_encrypt(aes, a, ppos);
- xor_aes_block(ppos, mpos);
- ppos += AES_BLOCK_SIZE;
- mpos += AES_BLOCK_SIZE;
- }
- if (last) {
- WPA_PUT_BE16(&a[14], i);
- aes_encrypt(aes, a, ppos);
- /* XOR zero-padded last block */
- for (i = 0; i < last; i++)
- *ppos++ ^= *mpos++;
- }
- wpa_hexdump(MSG_EXCESSIVE, "CCMP decrypted", plain, mlen);
-
- /* Authentication */
- /* B_0: Flags | Nonce N | l(m) */
- b[0] = 0x40 /* Adata */ | (3 /* M' */ << 3) | 1 /* L' */;
- os_memcpy(&b[1], nonce, 13);
- WPA_PUT_BE16(&b[14], mlen);
-
- wpa_hexdump(MSG_EXCESSIVE, "CCMP B_0", b, AES_BLOCK_SIZE);
- aes_encrypt(aes, b, x); /* X_1 = E(K, B_0) */
-
- wpa_hexdump(MSG_EXCESSIVE, "CCMP B_1", aad, AES_BLOCK_SIZE);
- xor_aes_block(aad, x);
- aes_encrypt(aes, aad, x); /* X_2 = E(K, X_1 XOR B_1) */
-
- wpa_hexdump(MSG_EXCESSIVE, "CCMP B_2", &aad[AES_BLOCK_SIZE],
- AES_BLOCK_SIZE);
- xor_aes_block(&aad[AES_BLOCK_SIZE], x);
- aes_encrypt(aes, &aad[AES_BLOCK_SIZE], x); /* X_3 = E(K, X_2 XOR B_2)
- */
-
- ppos = plain;
- for (i = 0; i < mlen / AES_BLOCK_SIZE; i++) {
- /* X_i+1 = E(K, X_i XOR B_i) */
- xor_aes_block(x, ppos);
- ppos += AES_BLOCK_SIZE;
- aes_encrypt(aes, x, x);
- }
- if (last) {
- /* XOR zero-padded last block */
- for (i = 0; i < last; i++)
- x[i] ^= *ppos++;
- aes_encrypt(aes, x, x);
- }
-
- aes_encrypt_deinit(aes);
-
- if (os_memcmp(x, t, 8) != 0) {
- u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
- wpa_printf(MSG_INFO, "Invalid CCMP MIC in frame: A1=" MACSTR
- " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
- MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3),
- WLAN_GET_SEQ_SEQ(seq_ctrl),
- WLAN_GET_SEQ_FRAG(seq_ctrl));
- wpa_hexdump(MSG_DEBUG, "CCMP decrypted", plain, mlen);
- os_free(plain);
- return NULL;
- }
-
- *decrypted_len = mlen;
- return plain;
-}
-
-
-void ccmp_get_pn(u8 *pn, const u8 *data)
-{
- pn[0] = data[7]; /* PN5 */
- pn[1] = data[6]; /* PN4 */
- pn[2] = data[5]; /* PN3 */
- pn[3] = data[4]; /* PN2 */
- pn[4] = data[1]; /* PN1 */
- pn[5] = data[0]; /* PN0 */
-}
-
-
-u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
- u8 *pn, int keyid, size_t *encrypted_len)
-{
- u8 aad[2 + 30], nonce[13];
- size_t aad_len;
- u8 b[AES_BLOCK_SIZE], x[AES_BLOCK_SIZE], a[AES_BLOCK_SIZE];
- void *aes;
- u8 *crypt, *pos, *ppos, *mpos;
- size_t plen, last;
- struct ieee80211_hdr *hdr;
- int i;
-
- if (len < hdrlen || hdrlen < 24)
- return NULL;
- plen = len - hdrlen;
- last = plen % AES_BLOCK_SIZE;
-
- crypt = os_malloc(hdrlen + 8 + plen + 8 + AES_BLOCK_SIZE);
- if (crypt == NULL)
- return NULL;
-
- os_memcpy(crypt, frame, hdrlen);
- hdr = (struct ieee80211_hdr *) crypt;
- hdr->frame_control |= host_to_le16(WLAN_FC_ISWEP);
- pos = crypt + hdrlen;
- *pos++ = pn[5]; /* PN0 */
- *pos++ = pn[4]; /* PN1 */
- *pos++ = 0x00; /* Rsvd */
- *pos++ = 0x20 | (keyid << 6);
- *pos++ = pn[3]; /* PN2 */
- *pos++ = pn[2]; /* PN3 */
- *pos++ = pn[1]; /* PN4 */
- *pos++ = pn[0]; /* PN5 */
-
- aes = aes_encrypt_init(tk, 16);
- if (aes == NULL) {
- os_free(crypt);
- return NULL;
- }
-
- os_memset(aad, 0, sizeof(aad));
- ccmp_aad_nonce(hdr, crypt + hdrlen, &aad[2], &aad_len, nonce);
- WPA_PUT_BE16(aad, aad_len);
- wpa_hexdump(MSG_EXCESSIVE, "CCMP AAD", &aad[2], aad_len);
- wpa_hexdump(MSG_EXCESSIVE, "CCMP nonce", nonce, 13);
-
- /* Authentication */
- /* B_0: Flags | Nonce N | l(m) */
- b[0] = 0x40 /* Adata */ | (3 /* M' */ << 3) | 1 /* L' */;
- os_memcpy(&b[1], nonce, 13);
- WPA_PUT_BE16(&b[14], plen);
-
- wpa_hexdump(MSG_EXCESSIVE, "CCMP B_0", b, AES_BLOCK_SIZE);
- aes_encrypt(aes, b, x); /* X_1 = E(K, B_0) */
-
- wpa_hexdump(MSG_EXCESSIVE, "CCMP B_1", aad, AES_BLOCK_SIZE);
- xor_aes_block(aad, x);
- aes_encrypt(aes, aad, x); /* X_2 = E(K, X_1 XOR B_1) */
-
- wpa_hexdump(MSG_EXCESSIVE, "CCMP B_2", &aad[AES_BLOCK_SIZE],
- AES_BLOCK_SIZE);
- xor_aes_block(&aad[AES_BLOCK_SIZE], x);
- aes_encrypt(aes, &aad[AES_BLOCK_SIZE], x); /* X_3 = E(K, X_2 XOR B_2)
- */
-
- ppos = frame + hdrlen;
- for (i = 0; i < plen / AES_BLOCK_SIZE; i++) {
- /* X_i+1 = E(K, X_i XOR B_i) */
- xor_aes_block(x, ppos);
- ppos += AES_BLOCK_SIZE;
- aes_encrypt(aes, x, x);
- }
- if (last) {
- /* XOR zero-padded last block */
- for (i = 0; i < last; i++)
- x[i] ^= *ppos++;
- aes_encrypt(aes, x, x);
- }
-
- /* Encryption */
-
- /* CCM: M=8 L=2, Adata=1, M' = (M-2)/2 = 3, L' = L-1 = 1 */
-
- /* A_i = Flags | Nonce N | Counter i */
- a[0] = 0x01; /* Flags = L' */
- os_memcpy(&a[1], nonce, 13);
-
- ppos = crypt + hdrlen + 8;
-
- /* crypt = msg XOR (S_1 | S_2 | ... | S_n) */
- mpos = frame + hdrlen;
- for (i = 1; i <= plen / AES_BLOCK_SIZE; i++) {
- WPA_PUT_BE16(&a[14], i);
- /* S_i = E(K, A_i) */
- aes_encrypt(aes, a, ppos);
- xor_aes_block(ppos, mpos);
- ppos += AES_BLOCK_SIZE;
- mpos += AES_BLOCK_SIZE;
- }
- if (last) {
- WPA_PUT_BE16(&a[14], i);
- aes_encrypt(aes, a, ppos);
- /* XOR zero-padded last block */
- for (i = 0; i < last; i++)
- *ppos++ ^= *mpos++;
- }
-
- wpa_hexdump(MSG_EXCESSIVE, "CCMP T", x, 8);
- /* U = T XOR S_0; S_0 = E(K, A_0) */
- WPA_PUT_BE16(&a[14], 0);
- aes_encrypt(aes, a, b);
- for (i = 0; i < 8; i++)
- ppos[i] = x[i] ^ b[i];
- wpa_hexdump(MSG_EXCESSIVE, "CCMP U", ppos, 8);
-
- wpa_hexdump(MSG_EXCESSIVE, "CCMP encrypted", crypt + hdrlen + 8, plen);
-
- aes_encrypt_deinit(aes);
-
- *encrypted_len = hdrlen + 8 + plen + 8;
-
- return crypt;
-}
diff --git a/wlantest/crc32.c b/wlantest/crc32.c
deleted file mode 100644
index adbbda5..0000000
--- a/wlantest/crc32.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 32-bit CRC for FCS calculation
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-
-/*
- * IEEE 802.11 FCS CRC32
- * G(x) = x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 +
- * x^5 + x^4 + x^2 + x + 1
- */
-static const u32 crc32_table[256] = {
- 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
- 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
- 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
- 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
- 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
- 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
- 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
- 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
- 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
- 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
- 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
- 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
- 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
- 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
- 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
- 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
- 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
- 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
- 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
- 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
- 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
- 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
- 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
- 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
- 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
- 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
- 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
- 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
- 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
- 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
- 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
- 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
- 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
- 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
- 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
- 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
- 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
- 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
- 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
- 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
- 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
- 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
- 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
- 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
- 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
- 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
- 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
- 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
- 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
- 0x2d02ef8d
-};
-
-
-u32 crc32(const u8 *frame, size_t frame_len)
-{
- size_t i;
- u32 crc;
-
- crc = 0xFFFFFFFF;
- for (i = 0; i < frame_len; i++)
- crc = crc32_table[(crc ^ frame[i]) & 0xff] ^ (crc >> 8);
-
- return ~crc;
-}
diff --git a/wlantest/ctrl.c b/wlantest/ctrl.c
deleted file mode 100644
index bed5d6c..0000000
--- a/wlantest/ctrl.c
+++ /dev/null
@@ -1,1364 +0,0 @@
-/*
- * wlantest control interface
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include <sys/un.h>
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "common/defs.h"
-#include "common/version.h"
-#include "common/ieee802_11_defs.h"
-#include "wlantest.h"
-#include "wlantest_ctrl.h"
-
-
-static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
- size_t *len)
-{
- u8 *pos = buf;
-
- while (pos + 8 <= buf + buflen) {
- enum wlantest_ctrl_attr a;
- size_t alen;
- a = WPA_GET_BE32(pos);
- pos += 4;
- alen = WPA_GET_BE32(pos);
- pos += 4;
- if (pos + alen > buf + buflen) {
- wpa_printf(MSG_DEBUG, "Invalid control message "
- "attribute");
- return NULL;
- }
- if (a == attr) {
- *len = alen;
- return pos;
- }
- pos += alen;
- }
-
- return NULL;
-}
-
-
-static u8 * attr_get_macaddr(u8 *buf, size_t buflen,
- enum wlantest_ctrl_attr attr)
-{
- u8 *addr;
- size_t addr_len;
- addr = attr_get(buf, buflen, attr, &addr_len);
- if (addr && addr_len != ETH_ALEN)
- addr = NULL;
- return addr;
-}
-
-
-static int attr_get_int(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr)
-{
- u8 *pos;
- size_t len;
- pos = attr_get(buf, buflen, attr, &len);
- if (pos == NULL || len != 4)
- return -1;
- return WPA_GET_BE32(pos);
-}
-
-
-static u8 * attr_add_str(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
- const char *str)
-{
- size_t len = os_strlen(str);
-
- if (pos == NULL || end - pos < 8 + len)
- return NULL;
- WPA_PUT_BE32(pos, attr);
- pos += 4;
- WPA_PUT_BE32(pos, len);
- pos += 4;
- os_memcpy(pos, str, len);
- pos += len;
- return pos;
-}
-
-
-static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
- u32 val)
-{
- if (pos == NULL || end - pos < 12)
- return NULL;
- WPA_PUT_BE32(pos, attr);
- pos += 4;
- WPA_PUT_BE32(pos, 4);
- pos += 4;
- WPA_PUT_BE32(pos, val);
- pos += 4;
- return pos;
-}
-
-
-static void ctrl_disconnect(struct wlantest *wt, int sock)
-{
- int i;
- wpa_printf(MSG_DEBUG, "Disconnect control interface connection %d",
- sock);
- for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
- if (wt->ctrl_socks[i] == sock) {
- close(wt->ctrl_socks[i]);
- eloop_unregister_read_sock(wt->ctrl_socks[i]);
- wt->ctrl_socks[i] = -1;
- break;
- }
- }
-}
-
-
-static void ctrl_send(struct wlantest *wt, int sock, const u8 *buf,
- size_t len)
-{
- if (send(sock, buf, len, 0) < 0) {
- wpa_printf(MSG_INFO, "send(ctrl): %s", strerror(errno));
- ctrl_disconnect(wt, sock);
- }
-}
-
-
-static void ctrl_send_simple(struct wlantest *wt, int sock,
- enum wlantest_ctrl_cmd cmd)
-{
- u8 buf[4];
- WPA_PUT_BE32(buf, cmd);
- ctrl_send(wt, sock, buf, sizeof(buf));
-}
-
-
-static struct wlantest_bss * ctrl_get_bss(struct wlantest *wt, int sock,
- u8 *cmd, size_t clen)
-{
- struct wlantest_bss *bss;
- u8 *pos;
- size_t len;
-
- pos = attr_get(cmd, clen, WLANTEST_ATTR_BSSID, &len);
- if (pos == NULL || len != ETH_ALEN) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return NULL;
- }
-
- bss = bss_find(wt, pos);
- if (bss == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return NULL;
- }
-
- return bss;
-}
-
-
-static struct wlantest_sta * ctrl_get_sta(struct wlantest *wt, int sock,
- u8 *cmd, size_t clen,
- struct wlantest_bss *bss)
-{
- struct wlantest_sta *sta;
- u8 *pos;
- size_t len;
-
- if (bss == NULL)
- return NULL;
-
- pos = attr_get(cmd, clen, WLANTEST_ATTR_STA_ADDR, &len);
- if (pos == NULL || len != ETH_ALEN) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return NULL;
- }
-
- sta = sta_find(bss, pos);
- if (sta == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return NULL;
- }
-
- return sta;
-}
-
-
-static struct wlantest_sta * ctrl_get_sta2(struct wlantest *wt, int sock,
- u8 *cmd, size_t clen,
- struct wlantest_bss *bss)
-{
- struct wlantest_sta *sta;
- u8 *pos;
- size_t len;
-
- if (bss == NULL)
- return NULL;
-
- pos = attr_get(cmd, clen, WLANTEST_ATTR_STA2_ADDR, &len);
- if (pos == NULL || len != ETH_ALEN) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return NULL;
- }
-
- sta = sta_find(bss, pos);
- if (sta == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return NULL;
- }
-
- return sta;
-}
-
-
-static void ctrl_list_bss(struct wlantest *wt, int sock)
-{
- u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
- struct wlantest_bss *bss;
-
- pos = buf;
- WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
- pos += 4;
- WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
- pos += 4;
- len = pos; /* to be filled */
- pos += 4;
-
- dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
- if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
- break;
- os_memcpy(pos, bss->bssid, ETH_ALEN);
- pos += ETH_ALEN;
- }
-
- WPA_PUT_BE32(len, pos - len - 4);
- ctrl_send(wt, sock, buf, pos - buf);
-}
-
-
-static void ctrl_list_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
-{
- u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos, *len;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
-
- bss = ctrl_get_bss(wt, sock, cmd, clen);
- if (bss == NULL)
- return;
-
- pos = buf;
- WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
- pos += 4;
- WPA_PUT_BE32(pos, WLANTEST_ATTR_STA_ADDR);
- pos += 4;
- len = pos; /* to be filled */
- pos += 4;
-
- dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
- if (pos + ETH_ALEN > buf + WLANTEST_CTRL_MAX_RESP_LEN)
- break;
- os_memcpy(pos, sta->addr, ETH_ALEN);
- pos += ETH_ALEN;
- }
-
- WPA_PUT_BE32(len, pos - len - 4);
- ctrl_send(wt, sock, buf, pos - buf);
-}
-
-
-static void ctrl_flush(struct wlantest *wt, int sock)
-{
- wpa_printf(MSG_DEBUG, "Drop all collected BSS data");
- bss_flush(wt);
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
-}
-
-
-static void ctrl_clear_sta_counters(struct wlantest *wt, int sock, u8 *cmd,
- size_t clen)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
-
- bss = ctrl_get_bss(wt, sock, cmd, clen);
- sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
- if (sta == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
-
- os_memset(sta->counters, 0, sizeof(sta->counters));
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
-}
-
-
-static void ctrl_clear_bss_counters(struct wlantest *wt, int sock, u8 *cmd,
- size_t clen)
-{
- struct wlantest_bss *bss;
-
- bss = ctrl_get_bss(wt, sock, cmd, clen);
- if (bss == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
-
- os_memset(bss->counters, 0, sizeof(bss->counters));
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
-}
-
-
-static void ctrl_clear_tdls_counters(struct wlantest *wt, int sock, u8 *cmd,
- size_t clen)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- struct wlantest_sta *sta2;
- struct wlantest_tdls *tdls;
-
- bss = ctrl_get_bss(wt, sock, cmd, clen);
- sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
- sta2 = ctrl_get_sta2(wt, sock, cmd, clen, bss);
- if (sta == NULL || sta2 == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
-
- dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
- if ((tdls->init == sta && tdls->resp == sta2) ||
- (tdls->init == sta2 && tdls->resp == sta))
- os_memset(tdls->counters, 0, sizeof(tdls->counters));
- }
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
-}
-
-
-static void ctrl_get_sta_counter(struct wlantest *wt, int sock, u8 *cmd,
- size_t clen)
-{
- u8 *addr;
- size_t addr_len;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- u32 counter;
- u8 buf[4 + 12], *end, *pos;
-
- bss = ctrl_get_bss(wt, sock, cmd, clen);
- sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
- if (sta == NULL)
- return;
-
- addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_COUNTER, &addr_len);
- if (addr == NULL || addr_len != 4) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
- counter = WPA_GET_BE32(addr);
- if (counter >= NUM_WLANTEST_STA_COUNTER) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
- pos += 4;
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
- sta->counters[counter]);
- ctrl_send(wt, sock, buf, pos - buf);
-}
-
-
-static void ctrl_get_bss_counter(struct wlantest *wt, int sock, u8 *cmd,
- size_t clen)
-{
- u8 *addr;
- size_t addr_len;
- struct wlantest_bss *bss;
- u32 counter;
- u8 buf[4 + 12], *end, *pos;
-
- bss = ctrl_get_bss(wt, sock, cmd, clen);
- if (bss == NULL)
- return;
-
- addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_COUNTER, &addr_len);
- if (addr == NULL || addr_len != 4) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
- counter = WPA_GET_BE32(addr);
- if (counter >= NUM_WLANTEST_BSS_COUNTER) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
- pos += 4;
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
- bss->counters[counter]);
- ctrl_send(wt, sock, buf, pos - buf);
-}
-
-
-static void ctrl_get_tdls_counter(struct wlantest *wt, int sock, u8 *cmd,
- size_t clen)
-{
- u8 *addr;
- size_t addr_len;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- struct wlantest_sta *sta2;
- struct wlantest_tdls *tdls;
- u32 counter;
- u8 buf[4 + 12], *end, *pos;
- int found = 0;
-
- bss = ctrl_get_bss(wt, sock, cmd, clen);
- sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
- sta2 = ctrl_get_sta2(wt, sock, cmd, clen, bss);
- if (sta == NULL || sta2 == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
-
- addr = attr_get(cmd, clen, WLANTEST_ATTR_TDLS_COUNTER, &addr_len);
- if (addr == NULL || addr_len != 4) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
- counter = WPA_GET_BE32(addr);
- if (counter >= NUM_WLANTEST_TDLS_COUNTER) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
-
- dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
- if (tdls->init == sta && tdls->resp == sta2) {
- found = 1;
- break;
- }
- }
-
- if (!found) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
- pos += 4;
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_COUNTER,
- tdls->counters[counter]);
- ctrl_send(wt, sock, buf, pos - buf);
-}
-
-
-static void build_mgmt_hdr(struct ieee80211_mgmt *mgmt,
- struct wlantest_bss *bss, struct wlantest_sta *sta,
- int sender_ap, int stype)
-{
- os_memset(mgmt, 0, 24);
- mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, stype);
- if (sender_ap) {
- if (sta)
- os_memcpy(mgmt->da, sta->addr, ETH_ALEN);
- else
- os_memset(mgmt->da, 0xff, ETH_ALEN);
- os_memcpy(mgmt->sa, bss->bssid, ETH_ALEN);
- } else {
- os_memcpy(mgmt->da, bss->bssid, ETH_ALEN);
- os_memcpy(mgmt->sa, sta->addr, ETH_ALEN);
- }
- os_memcpy(mgmt->bssid, bss->bssid, ETH_ALEN);
-}
-
-
-static int ctrl_inject_auth(struct wlantest *wt, struct wlantest_bss *bss,
- struct wlantest_sta *sta, int sender_ap,
- enum wlantest_inject_protection prot)
-{
- struct ieee80211_mgmt mgmt;
-
- if (prot != WLANTEST_INJECT_NORMAL &&
- prot != WLANTEST_INJECT_UNPROTECTED)
- return -1; /* Authentication frame is never protected */
- if (sta == NULL)
- return -1; /* No broadcast Authentication frames */
-
- if (sender_ap)
- wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
- MAC2STR(bss->bssid), MAC2STR(sta->addr));
- else
- wpa_printf(MSG_INFO, "INJECT: Auth " MACSTR " -> " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_AUTH);
-
- mgmt.u.auth.auth_alg = host_to_le16(WLAN_AUTH_OPEN);
- mgmt.u.auth.auth_transaction = host_to_le16(1);
- mgmt.u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);
-
- return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 6,
- WLANTEST_INJECT_UNPROTECTED);
-}
-
-
-static int ctrl_inject_assocreq(struct wlantest *wt, struct wlantest_bss *bss,
- struct wlantest_sta *sta, int sender_ap,
- enum wlantest_inject_protection prot)
-{
- u8 *buf;
- struct ieee80211_mgmt *mgmt;
- int ret;
-
- if (prot != WLANTEST_INJECT_NORMAL &&
- prot != WLANTEST_INJECT_UNPROTECTED)
- return -1; /* Association Request frame is never protected */
- if (sta == NULL)
- return -1; /* No broadcast Association Request frames */
- if (sender_ap)
- return -1; /* No Association Request frame sent by AP */
- if (sta->assocreq_ies == NULL) {
- wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
- "Request available for " MACSTR,
- MAC2STR(sta->addr));
- return -1;
- }
-
- wpa_printf(MSG_INFO, "INJECT: AssocReq " MACSTR " -> " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
- if (buf == NULL)
- return -1;
- mgmt = (struct ieee80211_mgmt *) buf;
-
- build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ASSOC_REQ);
-
- mgmt->u.assoc_req.capab_info = host_to_le16(sta->assocreq_capab_info);
- mgmt->u.assoc_req.listen_interval =
- host_to_le16(sta->assocreq_listen_int);
- os_memcpy(mgmt->u.assoc_req.variable, sta->assocreq_ies,
- sta->assocreq_ies_len);
-
- ret = wlantest_inject(wt, bss, sta, buf,
- 24 + 4 + sta->assocreq_ies_len,
- WLANTEST_INJECT_UNPROTECTED);
- os_free(buf);
- return ret;
-}
-
-
-static int ctrl_inject_reassocreq(struct wlantest *wt,
- struct wlantest_bss *bss,
- struct wlantest_sta *sta, int sender_ap,
- enum wlantest_inject_protection prot)
-{
- u8 *buf;
- struct ieee80211_mgmt *mgmt;
- int ret;
-
- if (prot != WLANTEST_INJECT_NORMAL &&
- prot != WLANTEST_INJECT_UNPROTECTED)
- return -1; /* Reassociation Request frame is never protected */
- if (sta == NULL)
- return -1; /* No broadcast Reassociation Request frames */
- if (sender_ap)
- return -1; /* No Reassociation Request frame sent by AP */
- if (sta->assocreq_ies == NULL) {
- wpa_printf(MSG_INFO, "INJECT: No previous (Re)Association "
- "Request available for " MACSTR,
- MAC2STR(sta->addr));
- return -1;
- }
-
- wpa_printf(MSG_INFO, "INJECT: ReassocReq " MACSTR " -> " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- buf = os_malloc(sizeof(*mgmt) + sta->assocreq_ies_len);
- if (buf == NULL)
- return -1;
- mgmt = (struct ieee80211_mgmt *) buf;
-
- build_mgmt_hdr(mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_REASSOC_REQ);
-
- mgmt->u.reassoc_req.capab_info =
- host_to_le16(sta->assocreq_capab_info);
- mgmt->u.reassoc_req.listen_interval =
- host_to_le16(sta->assocreq_listen_int);
- os_memcpy(mgmt->u.reassoc_req.current_ap, bss->bssid, ETH_ALEN);
- os_memcpy(mgmt->u.reassoc_req.variable, sta->assocreq_ies,
- sta->assocreq_ies_len);
-
- ret = wlantest_inject(wt, bss, sta, buf,
- 24 + 10 + sta->assocreq_ies_len,
- WLANTEST_INJECT_UNPROTECTED);
- os_free(buf);
- return ret;
-}
-
-
-static int ctrl_inject_deauth(struct wlantest *wt, struct wlantest_bss *bss,
- struct wlantest_sta *sta, int sender_ap,
- enum wlantest_inject_protection prot)
-{
- struct ieee80211_mgmt mgmt;
-
- if (sender_ap) {
- if (sta)
- wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> "
- MACSTR,
- MAC2STR(bss->bssid), MAC2STR(sta->addr));
- else
- wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR
- " -> broadcast", MAC2STR(bss->bssid));
- } else
- wpa_printf(MSG_INFO, "INJECT: Deauth " MACSTR " -> " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DEAUTH);
-
- mgmt.u.deauth.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);
-
- return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
-}
-
-
-static int ctrl_inject_disassoc(struct wlantest *wt, struct wlantest_bss *bss,
- struct wlantest_sta *sta, int sender_ap,
- enum wlantest_inject_protection prot)
-{
- struct ieee80211_mgmt mgmt;
-
- if (sender_ap) {
- if (sta)
- wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> "
- MACSTR,
- MAC2STR(bss->bssid), MAC2STR(sta->addr));
- else
- wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR
- " -> broadcast", MAC2STR(bss->bssid));
- } else
- wpa_printf(MSG_INFO, "INJECT: Disassoc " MACSTR " -> " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_DISASSOC);
-
- mgmt.u.disassoc.reason_code = host_to_le16(WLAN_REASON_UNSPECIFIED);
-
- return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 2, prot);
-}
-
-
-static int ctrl_inject_saqueryreq(struct wlantest *wt,
- struct wlantest_bss *bss,
- struct wlantest_sta *sta, int sender_ap,
- enum wlantest_inject_protection prot)
-{
- struct ieee80211_mgmt mgmt;
-
- if (sta == NULL)
- return -1; /* No broadcast SA Query frames */
-
- if (sender_ap)
- wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
- MACSTR, MAC2STR(bss->bssid), MAC2STR(sta->addr));
- else
- wpa_printf(MSG_INFO, "INJECT: SA Query Request " MACSTR " -> "
- MACSTR, MAC2STR(sta->addr), MAC2STR(bss->bssid));
- build_mgmt_hdr(&mgmt, bss, sta, sender_ap, WLAN_FC_STYPE_ACTION);
-
- mgmt.u.action.category = WLAN_ACTION_SA_QUERY;
- mgmt.u.action.u.sa_query_req.action = WLAN_SA_QUERY_REQUEST;
- mgmt.u.action.u.sa_query_req.trans_id[0] = 0x12;
- mgmt.u.action.u.sa_query_req.trans_id[1] = 0x34;
- os_memcpy(sender_ap ? sta->ap_sa_query_tr : sta->sta_sa_query_tr,
- mgmt.u.action.u.sa_query_req.trans_id,
- WLAN_SA_QUERY_TR_ID_LEN);
- return wlantest_inject(wt, bss, sta, (u8 *) &mgmt, 24 + 4, prot);
-}
-
-
-static void ctrl_inject(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
-{
- u8 *bssid, *sta_addr;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- int frame, sender_ap, prot;
- int ret = 0;
-
- bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
- sta_addr = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_STA_ADDR);
- frame = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_FRAME);
- sender_ap = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_SENDER_AP);
- if (sender_ap < 0)
- sender_ap = 0;
- prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
- if (bssid == NULL || sta_addr == NULL || frame < 0 || prot < 0) {
- wpa_printf(MSG_INFO, "Invalid inject command parameters");
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
-
- bss = bss_find(wt, bssid);
- if (bss == NULL) {
- wpa_printf(MSG_INFO, "BSS not found for inject command");
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
-
- if (is_broadcast_ether_addr(sta_addr)) {
- if (!sender_ap) {
- wpa_printf(MSG_INFO, "Invalid broadcast inject "
- "command without sender_ap set");
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- } sta = NULL;
- } else {
- sta = sta_find(bss, sta_addr);
- if (sta == NULL) {
- wpa_printf(MSG_INFO, "Station not found for inject "
- "command");
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
- }
-
- switch (frame) {
- case WLANTEST_FRAME_AUTH:
- ret = ctrl_inject_auth(wt, bss, sta, sender_ap, prot);
- break;
- case WLANTEST_FRAME_ASSOCREQ:
- ret = ctrl_inject_assocreq(wt, bss, sta, sender_ap, prot);
- break;
- case WLANTEST_FRAME_REASSOCREQ:
- ret = ctrl_inject_reassocreq(wt, bss, sta, sender_ap, prot);
- break;
- case WLANTEST_FRAME_DEAUTH:
- ret = ctrl_inject_deauth(wt, bss, sta, sender_ap, prot);
- break;
- case WLANTEST_FRAME_DISASSOC:
- ret = ctrl_inject_disassoc(wt, bss, sta, sender_ap, prot);
- break;
- case WLANTEST_FRAME_SAQUERYREQ:
- ret = ctrl_inject_saqueryreq(wt, bss, sta, sender_ap, prot);
- break;
- default:
- wpa_printf(MSG_INFO, "Unsupported inject command frame %d",
- frame);
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
-
- if (ret)
- wpa_printf(MSG_INFO, "Failed to inject frame");
- else
- wpa_printf(MSG_INFO, "Frame injected successfully");
- ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
- WLANTEST_CTRL_FAILURE);
-}
-
-
-static void ctrl_version(struct wlantest *wt, int sock)
-{
- u8 buf[WLANTEST_CTRL_MAX_RESP_LEN], *pos;
-
- pos = buf;
- WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
- pos += 4;
- pos = attr_add_str(pos, buf + sizeof(buf), WLANTEST_ATTR_VERSION,
- VERSION_STR);
- ctrl_send(wt, sock, buf, pos - buf);
-}
-
-
-static void ctrl_add_passphrase(struct wlantest *wt, int sock, u8 *cmd,
- size_t clen)
-{
- u8 *passphrase;
- size_t len;
- struct wlantest_passphrase *p, *pa;
- u8 *bssid;
-
- passphrase = attr_get(cmd, clen, WLANTEST_ATTR_PASSPHRASE, &len);
- if (passphrase == NULL) {
- u8 *wepkey;
- char *key;
- enum wlantest_ctrl_cmd res;
-
- wepkey = attr_get(cmd, clen, WLANTEST_ATTR_WEPKEY, &len);
- if (wepkey == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
- key = os_zalloc(len + 1);
- if (key == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
- os_memcpy(key, wepkey, len);
- if (add_wep(wt, key) < 0)
- res = WLANTEST_CTRL_FAILURE;
- else
- res = WLANTEST_CTRL_SUCCESS;
- os_free(key);
- ctrl_send_simple(wt, sock, res);
- return;
- }
-
- if (len < 8 || len > 63) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
-
- p = os_zalloc(sizeof(*p));
- if (p == NULL) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
- os_memcpy(p->passphrase, passphrase, len);
- wpa_printf(MSG_INFO, "Add passphrase '%s'", p->passphrase);
-
- bssid = attr_get_macaddr(cmd, clen, WLANTEST_ATTR_BSSID);
- if (bssid) {
- os_memcpy(p->bssid, bssid, ETH_ALEN);
- wpa_printf(MSG_INFO, "Limit passphrase for BSSID " MACSTR,
- MAC2STR(p->bssid));
- }
-
- dl_list_for_each(pa, &wt->passphrase, struct wlantest_passphrase, list)
- {
- if (os_strcmp(p->passphrase, pa->passphrase) == 0 &&
- os_memcmp(p->bssid, pa->bssid, ETH_ALEN) == 0) {
- wpa_printf(MSG_INFO, "Passphrase was already known");
- os_free(p);
- p = NULL;
- break;
- }
- }
-
- if (p) {
- struct wlantest_bss *bss;
- dl_list_add(&wt->passphrase, &p->list);
- dl_list_for_each(bss, &wt->bss, struct wlantest_bss, list) {
- if (bssid &&
- os_memcmp(p->bssid, bss->bssid, ETH_ALEN) != 0)
- continue;
- bss_add_pmk_from_passphrase(bss, p->passphrase);
- }
- }
-
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
-}
-
-
-static void info_print_proto(char *buf, size_t len, int proto)
-{
- char *pos, *end;
-
- if (proto == 0) {
- os_snprintf(buf, len, "OPEN");
- return;
- }
-
- pos = buf;
- end = buf + len;
-
- if (proto & WPA_PROTO_WPA)
- pos += os_snprintf(pos, end - pos, "%sWPA",
- pos == buf ? "" : " ");
- if (proto & WPA_PROTO_RSN)
- pos += os_snprintf(pos, end - pos, "%sWPA2",
- pos == buf ? "" : " ");
-}
-
-
-static void info_print_cipher(char *buf, size_t len, int cipher)
-{
- char *pos, *end;
-
- if (cipher == 0) {
- os_snprintf(buf, len, "N/A");
- return;
- }
-
- pos = buf;
- end = buf + len;
-
- if (cipher & WPA_CIPHER_NONE)
- pos += os_snprintf(pos, end - pos, "%sNONE",
- pos == buf ? "" : " ");
- if (cipher & WPA_CIPHER_WEP40)
- pos += os_snprintf(pos, end - pos, "%sWEP40",
- pos == buf ? "" : " ");
- if (cipher & WPA_CIPHER_WEP104)
- pos += os_snprintf(pos, end - pos, "%sWEP104",
- pos == buf ? "" : " ");
- if (cipher & WPA_CIPHER_TKIP)
- pos += os_snprintf(pos, end - pos, "%sTKIP",
- pos == buf ? "" : " ");
- if (cipher & WPA_CIPHER_CCMP)
- pos += os_snprintf(pos, end - pos, "%sCCMP",
- pos == buf ? "" : " ");
- if (cipher & WPA_CIPHER_AES_128_CMAC)
- pos += os_snprintf(pos, end - pos, "%sBIP",
- pos == buf ? "" : " ");
-}
-
-
-static void info_print_key_mgmt(char *buf, size_t len, int key_mgmt)
-{
- char *pos, *end;
-
- if (key_mgmt == 0) {
- os_snprintf(buf, len, "N/A");
- return;
- }
-
- pos = buf;
- end = buf + len;
-
- if (key_mgmt & WPA_KEY_MGMT_IEEE8021X)
- pos += os_snprintf(pos, end - pos, "%sEAP",
- pos == buf ? "" : " ");
- if (key_mgmt & WPA_KEY_MGMT_PSK)
- pos += os_snprintf(pos, end - pos, "%sPSK",
- pos == buf ? "" : " ");
- if (key_mgmt & WPA_KEY_MGMT_WPA_NONE)
- pos += os_snprintf(pos, end - pos, "%sWPA-NONE",
- pos == buf ? "" : " ");
- if (key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X)
- pos += os_snprintf(pos, end - pos, "%sFT-EAP",
- pos == buf ? "" : " ");
- if (key_mgmt & WPA_KEY_MGMT_FT_PSK)
- pos += os_snprintf(pos, end - pos, "%sFT-PSK",
- pos == buf ? "" : " ");
- if (key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256)
- pos += os_snprintf(pos, end - pos, "%sEAP-SHA256",
- pos == buf ? "" : " ");
- if (key_mgmt & WPA_KEY_MGMT_PSK_SHA256)
- pos += os_snprintf(pos, end - pos, "%sPSK-SHA256",
- pos == buf ? "" : " ");
-}
-
-
-static void info_print_rsn_capab(char *buf, size_t len, int capab)
-{
- char *pos, *end;
-
- pos = buf;
- end = buf + len;
-
- if (capab & WPA_CAPABILITY_PREAUTH)
- pos += os_snprintf(pos, end - pos, "%sPREAUTH",
- pos == buf ? "" : " ");
- if (capab & WPA_CAPABILITY_NO_PAIRWISE)
- pos += os_snprintf(pos, end - pos, "%sNO_PAIRWISE",
- pos == buf ? "" : " ");
- if (capab & WPA_CAPABILITY_MFPR)
- pos += os_snprintf(pos, end - pos, "%sMFPR",
- pos == buf ? "" : " ");
- if (capab & WPA_CAPABILITY_MFPC)
- pos += os_snprintf(pos, end - pos, "%sMFPC",
- pos == buf ? "" : " ");
- if (capab & WPA_CAPABILITY_PEERKEY_ENABLED)
- pos += os_snprintf(pos, end - pos, "%sPEERKEY",
- pos == buf ? "" : " ");
-}
-
-
-static void info_print_state(char *buf, size_t len, int state)
-{
- switch (state) {
- case STATE1:
- os_strlcpy(buf, "NOT-AUTH", len);
- break;
- case STATE2:
- os_strlcpy(buf, "AUTH", len);
- break;
- case STATE3:
- os_strlcpy(buf, "AUTH+ASSOC", len);
- break;
- }
-}
-
-
-static void info_print_gtk(char *buf, size_t len, struct wlantest_sta *sta)
-{
- size_t pos;
-
- pos = os_snprintf(buf, len, "IDX=%d,GTK=", sta->gtk_idx);
- wpa_snprintf_hex(buf + pos, len - pos, sta->gtk, sta->gtk_len);
-}
-
-
-static void ctrl_info_sta(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
-{
- u8 *addr;
- size_t addr_len;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- enum wlantest_sta_info info;
- u8 buf[4 + 108], *end, *pos;
- char resp[100];
-
- bss = ctrl_get_bss(wt, sock, cmd, clen);
- sta = ctrl_get_sta(wt, sock, cmd, clen, bss);
- if (sta == NULL)
- return;
-
- addr = attr_get(cmd, clen, WLANTEST_ATTR_STA_INFO, &addr_len);
- if (addr == NULL || addr_len != 4) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
- info = WPA_GET_BE32(addr);
-
- resp[0] = '\0';
- switch (info) {
- case WLANTEST_STA_INFO_PROTO:
- info_print_proto(resp, sizeof(resp), sta->proto);
- break;
- case WLANTEST_STA_INFO_PAIRWISE:
- info_print_cipher(resp, sizeof(resp), sta->pairwise_cipher);
- break;
- case WLANTEST_STA_INFO_KEY_MGMT:
- info_print_key_mgmt(resp, sizeof(resp), sta->key_mgmt);
- break;
- case WLANTEST_STA_INFO_RSN_CAPAB:
- info_print_rsn_capab(resp, sizeof(resp), sta->rsn_capab);
- break;
- case WLANTEST_STA_INFO_STATE:
- info_print_state(resp, sizeof(resp), sta->state);
- break;
- case WLANTEST_STA_INFO_GTK:
- info_print_gtk(resp, sizeof(resp), sta);
- break;
- default:
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
- pos += 4;
- pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
- ctrl_send(wt, sock, buf, pos - buf);
-}
-
-
-static void ctrl_info_bss(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
-{
- u8 *addr;
- size_t addr_len;
- struct wlantest_bss *bss;
- enum wlantest_bss_info info;
- u8 buf[4 + 108], *end, *pos;
- char resp[100];
-
- bss = ctrl_get_bss(wt, sock, cmd, clen);
- if (bss == NULL)
- return;
-
- addr = attr_get(cmd, clen, WLANTEST_ATTR_BSS_INFO, &addr_len);
- if (addr == NULL || addr_len != 4) {
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
- info = WPA_GET_BE32(addr);
-
- resp[0] = '\0';
- switch (info) {
- case WLANTEST_BSS_INFO_PROTO:
- info_print_proto(resp, sizeof(resp), bss->proto);
- break;
- case WLANTEST_BSS_INFO_PAIRWISE:
- info_print_cipher(resp, sizeof(resp), bss->pairwise_cipher);
- break;
- case WLANTEST_BSS_INFO_GROUP:
- info_print_cipher(resp, sizeof(resp), bss->group_cipher);
- break;
- case WLANTEST_BSS_INFO_GROUP_MGMT:
- info_print_cipher(resp, sizeof(resp), bss->mgmt_group_cipher);
- break;
- case WLANTEST_BSS_INFO_KEY_MGMT:
- info_print_key_mgmt(resp, sizeof(resp), bss->key_mgmt);
- break;
- case WLANTEST_BSS_INFO_RSN_CAPAB:
- info_print_rsn_capab(resp, sizeof(resp), bss->rsn_capab);
- break;
- default:
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_SUCCESS);
- pos += 4;
- pos = attr_add_str(pos, end, WLANTEST_ATTR_INFO, resp);
- ctrl_send(wt, sock, buf, pos - buf);
-}
-
-
-static void ctrl_send_(struct wlantest *wt, int sock, u8 *cmd, size_t clen)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- u8 *bssid, *sta_addr;
- int prot;
- u8 *frame;
- size_t frame_len;
- int ret = 0;
- struct ieee80211_hdr *hdr;
- u16 fc;
-
- frame = attr_get(cmd, clen, WLANTEST_ATTR_FRAME, &frame_len);
- prot = attr_get_int(cmd, clen, WLANTEST_ATTR_INJECT_PROTECTION);
- if (frame == NULL || frame_len < 24 || prot < 0) {
- wpa_printf(MSG_INFO, "Invalid send command parameters");
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_INVALID_CMD);
- return;
- }
-
- hdr = (struct ieee80211_hdr *) frame;
- fc = le_to_host16(hdr->frame_control);
- switch (WLAN_FC_GET_TYPE(fc)) {
- case WLAN_FC_TYPE_MGMT:
- bssid = hdr->addr3;
- if (os_memcmp(hdr->addr2, hdr->addr3, ETH_ALEN) == 0)
- sta_addr = hdr->addr1;
- else
- sta_addr = hdr->addr2;
- break;
- case WLAN_FC_TYPE_DATA:
- switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
- case 0:
- bssid = hdr->addr3;
- sta_addr = hdr->addr2;
- break;
- case WLAN_FC_TODS:
- bssid = hdr->addr1;
- sta_addr = hdr->addr2;
- break;
- case WLAN_FC_FROMDS:
- bssid = hdr->addr2;
- sta_addr = hdr->addr1;
- break;
- default:
- wpa_printf(MSG_INFO, "Unsupported inject frame");
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
- break;
- default:
- wpa_printf(MSG_INFO, "Unsupported inject frame");
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
-
- bss = bss_find(wt, bssid);
- if (bss == NULL && prot != WLANTEST_INJECT_UNPROTECTED) {
- wpa_printf(MSG_INFO, "Unknown BSSID");
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
-
- if (bss)
- sta = sta_find(bss, sta_addr);
- else
- sta = NULL;
- if (sta == NULL && prot != WLANTEST_INJECT_UNPROTECTED) {
- wpa_printf(MSG_INFO, "Unknown STA address");
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_FAILURE);
- return;
- }
-
- ret = wlantest_inject(wt, bss, sta, frame, frame_len, prot);
-
- if (ret)
- wpa_printf(MSG_INFO, "Failed to inject frame");
- else
- wpa_printf(MSG_INFO, "Frame injected successfully");
- ctrl_send_simple(wt, sock, ret == 0 ? WLANTEST_CTRL_SUCCESS :
- WLANTEST_CTRL_FAILURE);
-}
-
-
-static void ctrl_read(int sock, void *eloop_ctx, void *sock_ctx)
-{
- struct wlantest *wt = eloop_ctx;
- u8 buf[WLANTEST_CTRL_MAX_CMD_LEN];
- int len;
- enum wlantest_ctrl_cmd cmd;
-
- wpa_printf(MSG_EXCESSIVE, "New control interface message from %d",
- sock);
- len = recv(sock, buf, sizeof(buf), 0);
- if (len < 0) {
- wpa_printf(MSG_INFO, "recv(ctrl): %s", strerror(errno));
- ctrl_disconnect(wt, sock);
- return;
- }
- if (len == 0) {
- ctrl_disconnect(wt, sock);
- return;
- }
-
- if (len < 4) {
- wpa_printf(MSG_INFO, "Too short control interface command "
- "from %d", sock);
- ctrl_disconnect(wt, sock);
- return;
- }
- cmd = WPA_GET_BE32(buf);
- wpa_printf(MSG_EXCESSIVE, "Control interface command %d from %d",
- cmd, sock);
-
- switch (cmd) {
- case WLANTEST_CTRL_PING:
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
- break;
- case WLANTEST_CTRL_TERMINATE:
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_SUCCESS);
- eloop_terminate();
- break;
- case WLANTEST_CTRL_LIST_BSS:
- ctrl_list_bss(wt, sock);
- break;
- case WLANTEST_CTRL_LIST_STA:
- ctrl_list_sta(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_FLUSH:
- ctrl_flush(wt, sock);
- break;
- case WLANTEST_CTRL_CLEAR_STA_COUNTERS:
- ctrl_clear_sta_counters(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_CLEAR_BSS_COUNTERS:
- ctrl_clear_bss_counters(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_CLEAR_TDLS_COUNTERS:
- ctrl_clear_tdls_counters(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_GET_STA_COUNTER:
- ctrl_get_sta_counter(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_GET_BSS_COUNTER:
- ctrl_get_bss_counter(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_GET_TDLS_COUNTER:
- ctrl_get_tdls_counter(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_INJECT:
- ctrl_inject(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_VERSION:
- ctrl_version(wt, sock);
- break;
- case WLANTEST_CTRL_ADD_PASSPHRASE:
- ctrl_add_passphrase(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_INFO_STA:
- ctrl_info_sta(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_INFO_BSS:
- ctrl_info_bss(wt, sock, buf + 4, len - 4);
- break;
- case WLANTEST_CTRL_SEND:
- ctrl_send_(wt, sock, buf + 4, len - 4);
- break;
- default:
- ctrl_send_simple(wt, sock, WLANTEST_CTRL_UNKNOWN_CMD);
- break;
- }
-}
-
-
-static void ctrl_connect(int sock, void *eloop_ctx, void *sock_ctx)
-{
- struct wlantest *wt = eloop_ctx;
- int conn, i;
-
- conn = accept(sock, NULL, NULL);
- if (conn < 0) {
- wpa_printf(MSG_INFO, "accept(ctrl): %s", strerror(errno));
- return;
- }
- wpa_printf(MSG_MSGDUMP, "New control interface connection %d", conn);
-
- for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
- if (wt->ctrl_socks[i] < 0)
- break;
- }
-
- if (i == MAX_CTRL_CONNECTIONS) {
- wpa_printf(MSG_INFO, "No room for new control connection");
- close(conn);
- return;
- }
-
- wt->ctrl_socks[i] = conn;
- eloop_register_read_sock(conn, ctrl_read, wt, NULL);
-}
-
-
-int ctrl_init(struct wlantest *wt)
-{
- struct sockaddr_un addr;
-
- wt->ctrl_sock = socket(AF_UNIX, SOCK_SEQPACKET, 0);
- if (wt->ctrl_sock < 0) {
- wpa_printf(MSG_ERROR, "socket: %s", strerror(errno));
- return -1;
- }
-
- os_memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- os_strlcpy(addr.sun_path + 1, WLANTEST_SOCK_NAME,
- sizeof(addr.sun_path) - 1);
- if (bind(wt->ctrl_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- wpa_printf(MSG_ERROR, "bind: %s", strerror(errno));
- close(wt->ctrl_sock);
- wt->ctrl_sock = -1;
- return -1;
- }
-
- if (listen(wt->ctrl_sock, 5) < 0) {
- wpa_printf(MSG_ERROR, "listen: %s", strerror(errno));
- close(wt->ctrl_sock);
- wt->ctrl_sock = -1;
- return -1;
- }
-
- if (eloop_register_read_sock(wt->ctrl_sock, ctrl_connect, wt, NULL)) {
- close(wt->ctrl_sock);
- wt->ctrl_sock = -1;
- return -1;
- }
-
- return 0;
-}
-
-
-void ctrl_deinit(struct wlantest *wt)
-{
- int i;
-
- if (wt->ctrl_sock < 0)
- return;
-
- for (i = 0; i < MAX_CTRL_CONNECTIONS; i++) {
- if (wt->ctrl_socks[i] >= 0) {
- close(wt->ctrl_socks[i]);
- eloop_unregister_read_sock(wt->ctrl_socks[i]);
- wt->ctrl_socks[i] = -1;
- }
- }
-
- eloop_unregister_read_sock(wt->ctrl_sock);
- close(wt->ctrl_sock);
- wt->ctrl_sock = -1;
-}
diff --git a/wlantest/inject.c b/wlantest/inject.c
deleted file mode 100644
index b57f23f..0000000
--- a/wlantest/inject.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * wlantest frame injection
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/defs.h"
-#include "common/ieee802_11_defs.h"
-#include "crypto/aes_wrap.h"
-#include "wlantest.h"
-
-
-static int inject_frame(int s, const void *data, size_t len)
-{
-#define IEEE80211_RADIOTAP_F_FRAG 0x08
- unsigned char rtap_hdr[] = {
- 0x00, 0x00, /* radiotap version */
- 0x0e, 0x00, /* radiotap length */
- 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */
- IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */
- 0x00, /* padding */
- 0x00, 0x00, /* RX and TX flags to indicate that */
- 0x00, 0x00, /* this is the injected frame directly */
- };
- struct iovec iov[2] = {
- {
- .iov_base = &rtap_hdr,
- .iov_len = sizeof(rtap_hdr),
- },
- {
- .iov_base = (void *) data,
- .iov_len = len,
- }
- };
- struct msghdr msg = {
- .msg_name = NULL,
- .msg_namelen = 0,
- .msg_iov = iov,
- .msg_iovlen = 2,
- .msg_control = NULL,
- .msg_controllen = 0,
- .msg_flags = 0,
- };
- int ret;
-
- ret = sendmsg(s, &msg, 0);
- if (ret < 0)
- perror("sendmsg");
- return ret;
-}
-
-
-static int is_robust_mgmt(u8 *frame, size_t len)
-{
- struct ieee80211_mgmt *mgmt;
- u16 fc, stype;
- if (len < 24)
- return 0;
- mgmt = (struct ieee80211_mgmt *) frame;
- fc = le_to_host16(mgmt->frame_control);
- if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT)
- return 0;
- stype = WLAN_FC_GET_STYPE(fc);
- if (stype == WLAN_FC_STYPE_DEAUTH || stype == WLAN_FC_STYPE_DISASSOC)
- return 1;
- if (stype == WLAN_FC_STYPE_ACTION) {
- if (len < 25)
- return 0;
- if (mgmt->u.action.category != WLAN_ACTION_PUBLIC)
- return 1;
- }
- return 0;
-}
-
-
-static int wlantest_inject_bip(struct wlantest *wt, struct wlantest_bss *bss,
- u8 *frame, size_t len, int incorrect_key)
-{
- u8 *prot, *pos, *buf;
- u8 mic[16];
- u8 dummy[16];
- int ret;
- u16 fc;
- struct ieee80211_hdr *hdr;
- size_t plen;
-
- if (!bss->igtk_set[bss->igtk_idx])
- return -1;
-
- plen = len + 18;
- prot = os_malloc(plen);
- if (prot == NULL)
- return -1;
- os_memcpy(prot, frame, len);
- pos = prot + len;
- *pos++ = WLAN_EID_MMIE;
- *pos++ = 16;
- WPA_PUT_LE16(pos, bss->igtk_idx);
- pos += 2;
- inc_byte_array(bss->ipn[bss->igtk_idx], 6);
- os_memcpy(pos, bss->ipn[bss->igtk_idx], 6);
- pos += 6;
- os_memset(pos, 0, 8); /* MIC */
-
- buf = os_malloc(plen + 20 - 24);
- if (buf == NULL) {
- os_free(prot);
- return -1;
- }
-
- /* BIP AAD: FC(masked) A1 A2 A3 */
- hdr = (struct ieee80211_hdr *) frame;
- fc = le_to_host16(hdr->frame_control);
- fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
- WPA_PUT_LE16(buf, fc);
- os_memcpy(buf + 2, hdr->addr1, 3 * ETH_ALEN);
- os_memcpy(buf + 20, prot + 24, plen - 24);
- wpa_hexdump(MSG_MSGDUMP, "BIP: AAD|Body(masked)", buf, plen + 20 - 24);
- /* MIC = L(AES-128-CMAC(AAD || Frame Body(masked)), 0, 64) */
- os_memset(dummy, 0x11, sizeof(dummy));
- if (omac1_aes_128(incorrect_key ? dummy : bss->igtk[bss->igtk_idx],
- buf, plen + 20 - 24, mic) < 0) {
- os_free(prot);
- os_free(buf);
- return -1;
- }
- os_free(buf);
-
- os_memcpy(pos, mic, 8);
- wpa_hexdump(MSG_DEBUG, "BIP MMIE MIC", pos, 8);
-
- ret = inject_frame(wt->monitor_sock, prot, plen);
- os_free(prot);
-
- return (ret < 0) ? -1 : 0;
-}
-
-
-static int wlantest_inject_prot_bc(struct wlantest *wt,
- struct wlantest_bss *bss,
- u8 *frame, size_t len, int incorrect_key)
-{
- u8 *crypt;
- size_t crypt_len;
- int ret;
- u8 dummy[64];
- u8 *pn;
- struct ieee80211_hdr *hdr;
- u16 fc;
- int hdrlen;
-
- hdr = (struct ieee80211_hdr *) frame;
- hdrlen = 24;
- fc = le_to_host16(hdr->frame_control);
-
- if (!bss->gtk_len[bss->gtk_idx])
- return -1;
-
- if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
- (WLAN_FC_TODS | WLAN_FC_FROMDS))
- hdrlen += ETH_ALEN;
- pn = bss->rsc[bss->gtk_idx];
- inc_byte_array(pn, 6);
-
- os_memset(dummy, 0x11, sizeof(dummy));
- if (bss->group_cipher == WPA_CIPHER_TKIP)
- crypt = tkip_encrypt(incorrect_key ? dummy :
- bss->gtk[bss->gtk_idx],
- frame, len, hdrlen, NULL, pn,
- bss->gtk_idx, &crypt_len);
- else
- crypt = ccmp_encrypt(incorrect_key ? dummy :
- bss->gtk[bss->gtk_idx],
- frame, len, hdrlen, NULL, pn,
- bss->gtk_idx, &crypt_len);
-
- if (crypt == NULL)
- return -1;
-
- ret = inject_frame(wt->monitor_sock, crypt, crypt_len);
- os_free(crypt);
-
- return (ret < 0) ? -1 : 0;
-}
-
-
-static int wlantest_inject_prot(struct wlantest *wt, struct wlantest_bss *bss,
- struct wlantest_sta *sta, u8 *frame,
- size_t len, int incorrect_key)
-{
- u8 *crypt;
- size_t crypt_len;
- int ret;
- u8 dummy[64];
- u8 *pn;
- struct ieee80211_hdr *hdr;
- u16 fc;
- int tid = 0;
- u8 *qos = NULL;
- int hdrlen;
- struct wlantest_tdls *tdls = NULL;
- const u8 *tk = NULL;
-
- hdr = (struct ieee80211_hdr *) frame;
- hdrlen = 24;
- fc = le_to_host16(hdr->frame_control);
-
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
- (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == 0) {
- struct wlantest_sta *sta2;
- bss = bss_get(wt, hdr->addr3);
- if (bss == NULL) {
- wpa_printf(MSG_DEBUG, "No BSS found for TDLS "
- "injection");
- return -1;
- }
- sta = sta_find(bss, hdr->addr2);
- sta2 = sta_find(bss, hdr->addr1);
- if (sta == NULL || sta2 == NULL) {
- wpa_printf(MSG_DEBUG, "No stations found for TDLS "
- "injection");
- return -1;
- }
- dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list)
- {
- if ((tdls->init == sta && tdls->resp == sta2) ||
- (tdls->init == sta2 && tdls->resp == sta)) {
- if (!tdls->link_up)
- wpa_printf(MSG_DEBUG, "TDLS: Link not "
- "up, but injecting Data "
- "frame on direct link");
- tk = tdls->tpk.tk;
- break;
- }
- }
- }
-
- if (tk == NULL && sta == NULL) {
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
- return wlantest_inject_bip(wt, bss, frame, len,
- incorrect_key);
- return wlantest_inject_prot_bc(wt, bss, frame, len,
- incorrect_key);
- }
-
- if (tk == NULL && !sta->ptk_set) {
- wpa_printf(MSG_DEBUG, "No key known for injection");
- return -1;
- }
-
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
- tid = 16;
- else if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA) {
- if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
- (WLAN_FC_TODS | WLAN_FC_FROMDS))
- hdrlen += ETH_ALEN;
- if (WLAN_FC_GET_STYPE(fc) & 0x08) {
- qos = frame + hdrlen;
- hdrlen += 2;
- tid = qos[0] & 0x0f;
- }
- }
- if (tk) {
- if (os_memcmp(hdr->addr2, tdls->init->addr, ETH_ALEN) == 0)
- pn = tdls->rsc_init[tid];
- else
- pn = tdls->rsc_resp[tid];
- } else if (os_memcmp(hdr->addr2, bss->bssid, ETH_ALEN) == 0)
- pn = sta->rsc_fromds[tid];
- else
- pn = sta->rsc_tods[tid];
- inc_byte_array(pn, 6);
-
- os_memset(dummy, 0x11, sizeof(dummy));
- if (tk)
- crypt = ccmp_encrypt(incorrect_key ? dummy : tk,
- frame, len, hdrlen, qos, pn, 0,
- &crypt_len);
- else if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
- crypt = tkip_encrypt(incorrect_key ? dummy : sta->ptk.tk1,
- frame, len, hdrlen, qos, pn, 0,
- &crypt_len);
- else
- crypt = ccmp_encrypt(incorrect_key ? dummy : sta->ptk.tk1,
- frame, len, hdrlen, qos, pn, 0,
- &crypt_len);
-
- if (crypt == NULL) {
- wpa_printf(MSG_DEBUG, "Frame encryption failed");
- return -1;
- }
-
- wpa_hexdump(MSG_DEBUG, "Inject frame (encrypted)", crypt, crypt_len);
- ret = inject_frame(wt->monitor_sock, crypt, crypt_len);
- os_free(crypt);
- wpa_printf(MSG_DEBUG, "inject_frame for protected frame: %d", ret);
-
- return (ret < 0) ? -1 : 0;
-}
-
-
-int wlantest_inject(struct wlantest *wt, struct wlantest_bss *bss,
- struct wlantest_sta *sta, u8 *frame, size_t len,
- enum wlantest_inject_protection prot)
-{
- int ret;
- struct ieee80211_hdr *hdr;
- u16 fc;
- int protectable, protect = 0;
-
- wpa_hexdump(MSG_DEBUG, "Inject frame", frame, len);
- if (wt->monitor_sock < 0) {
- wpa_printf(MSG_INFO, "Cannot inject frames when monitor "
- "interface is not in use");
- return -1;
- }
-
- if (prot != WLANTEST_INJECT_UNPROTECTED &&
- (bss == NULL || sta == NULL)) {
- wpa_printf(MSG_INFO, "No BSS/STA information to inject "
- "protected frames");
- return -1;
- }
-
- hdr = (struct ieee80211_hdr *) frame;
- fc = le_to_host16(hdr->frame_control);
- protectable = WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA ||
- is_robust_mgmt(frame, len);
-
- if ((prot == WLANTEST_INJECT_PROTECTED ||
- prot == WLANTEST_INJECT_INCORRECT_KEY) && bss) {
- if (!sta &&
- ((WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
- !bss->igtk_set[bss->igtk_idx]) ||
- (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
- !bss->gtk_len[bss->gtk_idx]))) {
- wpa_printf(MSG_INFO, "No GTK/IGTK known for "
- MACSTR " to protect the injected "
- "frame", MAC2STR(bss->bssid));
- return -1;
- }
- if (sta && !sta->ptk_set) {
- wpa_printf(MSG_INFO, "No PTK known for the STA " MACSTR
- " to encrypt the injected frame",
- MAC2STR(sta->addr));
- return -1;
- }
- protect = 1;
- } else if (protectable && prot != WLANTEST_INJECT_UNPROTECTED && bss) {
- if (sta && sta->ptk_set)
- protect = 1;
- else if (!sta) {
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
- bss->gtk_len[bss->gtk_idx])
- protect = 1;
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
- bss->igtk_set[bss->igtk_idx])
- protect = 1;
- }
- }
-
- if (protect && bss)
- return wlantest_inject_prot(
- wt, bss, sta, frame, len,
- prot == WLANTEST_INJECT_INCORRECT_KEY);
-
- ret = inject_frame(wt->monitor_sock, frame, len);
- wpa_printf(MSG_DEBUG, "inject_frame for unprotected frame: %d", ret);
- return (ret < 0) ? -1 : 0;
-}
diff --git a/wlantest/monitor.c b/wlantest/monitor.c
deleted file mode 100644
index 902e6d9..0000000
--- a/wlantest/monitor.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Linux packet socket monitor
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include <net/if.h>
-#include <netpacket/packet.h>
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "wlantest.h"
-
-
-static void monitor_read(int sock, void *eloop_ctx, void *sock_ctx)
-{
- struct wlantest *wt = eloop_ctx;
- u8 buf[3000];
- int len;
-
- len = recv(sock, buf, sizeof(buf), 0);
- if (len < 0) {
- wpa_printf(MSG_INFO, "recv(PACKET): %s", strerror(errno));
- return;
- }
-
- write_pcap_captured(wt, buf, len);
- wlantest_process(wt, buf, len);
-}
-
-
-static void monitor_read_wired(int sock, void *eloop_ctx, void *sock_ctx)
-{
- struct wlantest *wt = eloop_ctx;
- u8 buf[3000];
- int len;
-
- len = recv(sock, buf, sizeof(buf), 0);
- if (len < 0) {
- wpa_printf(MSG_INFO, "recv(PACKET): %s", strerror(errno));
- return;
- }
-
- wlantest_process_wired(wt, buf, len);
-}
-
-
-int monitor_init(struct wlantest *wt, const char *ifname)
-{
- struct sockaddr_ll ll;
-
- os_memset(&ll, 0, sizeof(ll));
- ll.sll_family = AF_PACKET;
- ll.sll_ifindex = if_nametoindex(ifname);
- if (ll.sll_ifindex == 0) {
- wpa_printf(MSG_ERROR, "Monitor interface '%s' does not exist",
- ifname);
- return -1;
- }
-
- wt->monitor_sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
- if (wt->monitor_sock < 0) {
- wpa_printf(MSG_ERROR, "socket(PF_PACKET,SOCK_RAW): %s",
- strerror(errno));
- return -1;
- }
-
- if (bind(wt->monitor_sock, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
- wpa_printf(MSG_ERROR, "bind(PACKET): %s", strerror(errno));
- close(wt->monitor_sock);
- wt->monitor_sock = -1;
- return -1;
- }
-
- if (eloop_register_read_sock(wt->monitor_sock, monitor_read, wt, NULL))
- {
- wpa_printf(MSG_ERROR, "Could not register monitor read "
- "socket");
- close(wt->monitor_sock);
- wt->monitor_sock = -1;
- return -1;
- }
-
- return 0;
-}
-
-
-int monitor_init_wired(struct wlantest *wt, const char *ifname)
-{
- struct sockaddr_ll ll;
-
- os_memset(&ll, 0, sizeof(ll));
- ll.sll_family = AF_PACKET;
- ll.sll_ifindex = if_nametoindex(ifname);
- if (ll.sll_ifindex == 0) {
- wpa_printf(MSG_ERROR, "Monitor interface '%s' does not exist",
- ifname);
- return -1;
- }
-
- wt->monitor_wired = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
- if (wt->monitor_wired < 0) {
- wpa_printf(MSG_ERROR, "socket(PF_PACKET,SOCK_RAW): %s",
- strerror(errno));
- return -1;
- }
-
- if (bind(wt->monitor_wired, (struct sockaddr *) &ll, sizeof(ll)) < 0) {
- wpa_printf(MSG_ERROR, "bind(PACKET): %s", strerror(errno));
- close(wt->monitor_wired);
- wt->monitor_wired = -1;
- return -1;
- }
-
- if (eloop_register_read_sock(wt->monitor_wired, monitor_read_wired,
- wt, NULL)) {
- wpa_printf(MSG_ERROR, "Could not register monitor read "
- "socket");
- close(wt->monitor_wired);
- wt->monitor_wired = -1;
- return -1;
- }
-
- return 0;
-}
-
-
-void monitor_deinit(struct wlantest *wt)
-{
- if (wt->monitor_sock >= 0) {
- eloop_unregister_read_sock(wt->monitor_sock);
- close(wt->monitor_sock);
- wt->monitor_sock = -1;
- }
-
- if (wt->monitor_wired >= 0) {
- eloop_unregister_read_sock(wt->monitor_wired);
- close(wt->monitor_wired);
- wt->monitor_wired = -1;
- }
-}
diff --git a/wlantest/process.c b/wlantest/process.c
deleted file mode 100644
index dc272ed..0000000
--- a/wlantest/process.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Received frame processing
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/radiotap.h"
-#include "utils/radiotap_iter.h"
-#include "common/ieee802_11_defs.h"
-#include "wlantest.h"
-
-
-static struct wlantest_sta * rx_get_sta(struct wlantest *wt,
- const struct ieee80211_hdr *hdr,
- size_t len, int *to_ap)
-{
- u16 fc;
- const u8 *sta_addr, *bssid;
- struct wlantest_bss *bss;
-
- *to_ap = 0;
- if (hdr->addr1[0] & 0x01)
- return NULL; /* Ignore group addressed frames */
-
- fc = le_to_host16(hdr->frame_control);
- switch (WLAN_FC_GET_TYPE(fc)) {
- case WLAN_FC_TYPE_MGMT:
- if (len < 24)
- return NULL;
- 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 NULL; /* Unsupported STA-to-STA frame */
- sta_addr = hdr->addr2;
- *to_ap = 1;
- }
- break;
- case WLAN_FC_TYPE_DATA:
- if (len < 24)
- return NULL;
- switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
- case 0:
- return NULL; /* 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 NULL; /* WDS not supported */
- default:
- return NULL;
- }
- break;
- case WLAN_FC_TYPE_CTRL:
- if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PSPOLL &&
- len >= 16) {
- sta_addr = hdr->addr2;
- bssid = hdr->addr1;
- *to_ap = 1;
- } else
- return NULL;
- break;
- default:
- return NULL;
- }
-
- bss = bss_find(wt, bssid);
- if (bss == NULL)
- return NULL;
- return sta_find(bss, sta_addr);
-}
-
-
-static void rx_update_ps(struct wlantest *wt, const struct ieee80211_hdr *hdr,
- size_t len, struct wlantest_sta *sta, int to_ap)
-{
- u16 fc, type, stype;
-
- if (sta == NULL)
- return;
-
- fc = le_to_host16(hdr->frame_control);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
-
- if (!to_ap) {
- if (sta->pwrmgt && !sta->pspoll) {
- u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
- wpa_printf(MSG_DEBUG, "AP " MACSTR " sent a frame "
- "(%u:%u) to a sleeping STA " MACSTR
- " (seq=%u)",
- MAC2STR(sta->bss->bssid),
- type, stype, MAC2STR(sta->addr),
- WLAN_GET_SEQ_SEQ(seq_ctrl));
- } else
- sta->pspoll = 0;
- return;
- }
-
- sta->pspoll = 0;
-
- if (type == WLAN_FC_TYPE_DATA || type == WLAN_FC_TYPE_MGMT ||
- (type == WLAN_FC_TYPE_CTRL && stype == WLAN_FC_STYPE_PSPOLL)) {
- /*
- * In theory, the PS state changes only at the end of the frame
- * exchange that is ACKed by the AP. However, most cases are
- * handled with this simpler implementation that does not
- * maintain state through the frame exchange.
- */
- if (sta->pwrmgt && !(fc & WLAN_FC_PWRMGT)) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR " woke up from "
- "sleep", MAC2STR(sta->addr));
- sta->pwrmgt = 0;
- } else if (!sta->pwrmgt && (fc & WLAN_FC_PWRMGT)) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR " went to sleep",
- MAC2STR(sta->addr));
- sta->pwrmgt = 1;
- }
- }
-
- if (type == WLAN_FC_TYPE_CTRL && stype == WLAN_FC_STYPE_PSPOLL)
- sta->pspoll = 1;
-}
-
-
-static int rx_duplicate(struct wlantest *wt, const struct ieee80211_hdr *hdr,
- size_t len, struct wlantest_sta *sta, int to_ap)
-{
- u16 fc;
- int tid = 16;
- le16 *seq_ctrl;
-
- if (sta == NULL)
- return 0;
-
- fc = le_to_host16(hdr->frame_control);
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
- (WLAN_FC_GET_STYPE(fc) & 0x08) && len >= 26) {
- const u8 *qos = ((const u8 *) hdr) + 24;
- tid = qos[0] & 0x0f;
- }
-
- 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_ack(struct wlantest *wt, const struct ieee80211_hdr *hdr)
-{
- struct ieee80211_hdr *last = (struct ieee80211_hdr *) wt->last_hdr;
- u16 fc;
-
- if (wt->last_len < 24 || (last->addr1[0] & 0x01) ||
- os_memcmp(hdr->addr1, last->addr2, ETH_ALEN) != 0) {
- wpa_printf(MSG_MSGDUMP, "Unknown Ack frame (previous frame "
- "not seen)");
- return;
- }
-
- /* Ack to the previous frame */
- fc = le_to_host16(last->frame_control);
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT)
- rx_mgmt_ack(wt, last);
-}
-
-
-static void rx_frame(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_hdr *hdr;
- u16 fc;
- struct wlantest_sta *sta;
- int to_ap;
-
- wpa_hexdump(MSG_EXCESSIVE, "RX frame", data, len);
- if (len < 2)
- return;
-
- hdr = (const struct ieee80211_hdr *) data;
- fc = le_to_host16(hdr->frame_control);
- if (fc & WLAN_FC_PVER) {
- wpa_printf(MSG_DEBUG, "Drop RX frame with unexpected pver=%d",
- fc & WLAN_FC_PVER);
- return;
- }
-
- sta = rx_get_sta(wt, hdr, len, &to_ap);
-
- switch (WLAN_FC_GET_TYPE(fc)) {
- case WLAN_FC_TYPE_MGMT:
- if (len < 24)
- break;
- if (rx_duplicate(wt, hdr, len, sta, to_ap))
- break;
- rx_update_ps(wt, hdr, len, sta, to_ap);
- rx_mgmt(wt, data, len);
- break;
- case WLAN_FC_TYPE_CTRL:
- if (len < 10)
- break;
- wt->rx_ctrl++;
- rx_update_ps(wt, hdr, len, sta, to_ap);
- if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACK)
- rx_ack(wt, hdr);
- break;
- case WLAN_FC_TYPE_DATA:
- if (len < 24)
- break;
- if (rx_duplicate(wt, hdr, len, sta, to_ap))
- break;
- rx_update_ps(wt, hdr, len, sta, to_ap);
- rx_data(wt, data, len);
- break;
- default:
- wpa_printf(MSG_DEBUG, "Drop RX frame with unexpected type %d",
- WLAN_FC_GET_TYPE(fc));
- break;
- }
-
- os_memcpy(wt->last_hdr, data, len > sizeof(wt->last_hdr) ?
- sizeof(wt->last_hdr) : len);
- wt->last_len = len;
-}
-
-
-static void tx_status(struct wlantest *wt, const u8 *data, size_t len, int ack)
-{
- wpa_printf(MSG_DEBUG, "TX status: ack=%d", ack);
- wpa_hexdump(MSG_EXCESSIVE, "TX status frame", data, len);
-}
-
-
-static int check_fcs(const u8 *frame, size_t frame_len, const u8 *fcs)
-{
- if (WPA_GET_LE32(fcs) != crc32(frame, frame_len))
- return -1;
- return 0;
-}
-
-
-void wlantest_process(struct wlantest *wt, const u8 *data, size_t len)
-{
- struct ieee80211_radiotap_iterator iter;
- int ret;
- int rxflags = 0, txflags = 0, failed = 0, fcs = 0;
- const u8 *frame, *fcspos;
- size_t frame_len;
-
- wpa_hexdump(MSG_EXCESSIVE, "Process data", data, len);
-
- if (ieee80211_radiotap_iterator_init(&iter, (void *) data, len)) {
- wpa_printf(MSG_INFO, "Invalid radiotap frame");
- return;
- }
-
- for (;;) {
- ret = ieee80211_radiotap_iterator_next(&iter);
- wpa_printf(MSG_EXCESSIVE, "radiotap iter: %d "
- "this_arg_index=%d", ret, iter.this_arg_index);
- if (ret == -ENOENT)
- break;
- if (ret) {
- wpa_printf(MSG_INFO, "Invalid radiotap header: %d",
- ret);
- return;
- }
- switch (iter.this_arg_index) {
- case IEEE80211_RADIOTAP_FLAGS:
- if (*iter.this_arg & IEEE80211_RADIOTAP_F_FCS)
- fcs = 1;
- break;
- case IEEE80211_RADIOTAP_RX_FLAGS:
- rxflags = 1;
- break;
- case IEEE80211_RADIOTAP_TX_FLAGS:
- txflags = 1;
- failed = le_to_host16((*(u16 *) iter.this_arg)) &
- IEEE80211_RADIOTAP_F_TX_FAIL;
- break;
-
- }
- }
-
- if (iter.max_length == 8) {
- wpa_printf(MSG_DEBUG, "Skip frame inserted by wlantest");
- return;
- }
- frame = data + iter.max_length;
- frame_len = len - iter.max_length;
-
- 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;
- }
- }
-
- if (rxflags && txflags)
- return;
- if (!txflags)
- rx_frame(wt, frame, frame_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);
-}
-
-
-void wlantest_process_80211(struct wlantest *wt, const u8 *data, size_t len)
-{
- wpa_hexdump(MSG_EXCESSIVE, "Process data", data, len);
- rx_frame(wt, data, len);
-}
diff --git a/wlantest/readpcap.c b/wlantest/readpcap.c
deleted file mode 100644
index 3ab4080..0000000
--- a/wlantest/readpcap.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * PCAP capture file reader
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include <pcap.h>
-
-#include "utils/common.h"
-#include "wlantest.h"
-
-
-int read_cap_file(struct wlantest *wt, const char *fname)
-{
- char errbuf[PCAP_ERRBUF_SIZE];
- pcap_t *pcap;
- unsigned int count = 0;
- struct pcap_pkthdr *hdr;
- const u_char *data;
- int res;
- int dlt;
-
- pcap = pcap_open_offline(fname, errbuf);
- if (pcap == NULL) {
- wpa_printf(MSG_ERROR, "Failed to read pcap file '%s': %s",
- fname, errbuf);
- return -1;
- }
- dlt = pcap_datalink(pcap);
- if (dlt != DLT_IEEE802_11_RADIO && dlt != DLT_PRISM_HEADER &&
- dlt != DLT_IEEE802_11) {
- 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);
- if (res == -2)
- break; /* No more packets */
- if (res == -1) {
- wpa_printf(MSG_INFO, "pcap_next_ex failure: %s",
- pcap_geterr(pcap));
- break;
- }
- if (res != 1) {
- wpa_printf(MSG_INFO, "Unexpected pcap_next_ex return "
- "value %d", res);
- break;
- }
-
- /* Packet was read without problems */
- wpa_printf(MSG_EXCESSIVE, "pcap hdr: ts=%d.%06d "
- "len=%u/%u",
- (int) hdr->ts.tv_sec, (int) hdr->ts.tv_usec,
- hdr->caplen, hdr->len);
- if (wt->write_pcap_dumper) {
- wt->write_pcap_time = hdr->ts;
- pcap_dump(wt->write_pcap_dumper, hdr, data);
- }
- if (hdr->caplen < hdr->len) {
- wpa_printf(MSG_DEBUG, "pcap: Dropped incomplete frame "
- "(%u/%u captured)",
- hdr->caplen, hdr->len);
- continue;
- }
- count++;
- 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;
- case DLT_IEEE802_11:
- wlantest_process_80211(wt, data, hdr->caplen);
- }
- }
-
- pcap_close(pcap);
-
- wpa_printf(MSG_DEBUG, "Read %s: %u packets", fname, count);
-
- return 0;
-}
-
-
-int read_wired_cap_file(struct wlantest *wt, const char *fname)
-{
- char errbuf[PCAP_ERRBUF_SIZE];
- pcap_t *pcap;
- unsigned int count = 0;
- struct pcap_pkthdr *hdr;
- const u_char *data;
- int res;
-
- pcap = pcap_open_offline(fname, errbuf);
- if (pcap == NULL) {
- wpa_printf(MSG_ERROR, "Failed to read pcap file '%s': %s",
- fname, errbuf);
- return -1;
- }
-
- for (;;) {
- res = pcap_next_ex(pcap, &hdr, &data);
- if (res == -2)
- break; /* No more packets */
- if (res == -1) {
- wpa_printf(MSG_INFO, "pcap_next_ex failure: %s",
- pcap_geterr(pcap));
- break;
- }
- if (res != 1) {
- wpa_printf(MSG_INFO, "Unexpected pcap_next_ex return "
- "value %d", res);
- break;
- }
-
- /* Packet was read without problems */
- wpa_printf(MSG_EXCESSIVE, "pcap hdr: ts=%d.%06d "
- "len=%u/%u",
- (int) hdr->ts.tv_sec, (int) hdr->ts.tv_usec,
- hdr->caplen, hdr->len);
- if (hdr->caplen < hdr->len) {
- wpa_printf(MSG_DEBUG, "pcap: Dropped incomplete frame "
- "(%u/%u captured)",
- hdr->caplen, hdr->len);
- continue;
- }
- count++;
- wlantest_process_wired(wt, data, hdr->caplen);
- }
-
- pcap_close(pcap);
-
- wpa_printf(MSG_DEBUG, "Read %s: %u packets", fname, count);
-
- return 0;
-}
diff --git a/wlantest/rx_data.c b/wlantest/rx_data.c
deleted file mode 100644
index fea73cc..0000000
--- a/wlantest/rx_data.c
+++ /dev/null
@@ -1,529 +0,0 @@
-/*
- * Received Data frame processing
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include <linux/if_ether.h>
-
-#include "utils/common.h"
-#include "common/defs.h"
-#include "common/ieee802_11_defs.h"
-#include "wlantest.h"
-
-
-static const char * data_stype(u16 stype)
-{
- switch (stype) {
- case WLAN_FC_STYPE_DATA:
- return "DATA";
- case WLAN_FC_STYPE_DATA_CFACK:
- return "DATA-CFACK";
- case WLAN_FC_STYPE_DATA_CFPOLL:
- return "DATA-CFPOLL";
- case WLAN_FC_STYPE_DATA_CFACKPOLL:
- return "DATA-CFACKPOLL";
- case WLAN_FC_STYPE_NULLFUNC:
- return "NULLFUNC";
- case WLAN_FC_STYPE_CFACK:
- return "CFACK";
- case WLAN_FC_STYPE_CFPOLL:
- return "CFPOLL";
- case WLAN_FC_STYPE_CFACKPOLL:
- return "CFACKPOLL";
- case WLAN_FC_STYPE_QOS_DATA:
- return "QOSDATA";
- case WLAN_FC_STYPE_QOS_DATA_CFACK:
- return "QOSDATA-CFACK";
- case WLAN_FC_STYPE_QOS_DATA_CFPOLL:
- return "QOSDATA-CFPOLL";
- case WLAN_FC_STYPE_QOS_DATA_CFACKPOLL:
- return "QOSDATA-CFACKPOLL";
- case WLAN_FC_STYPE_QOS_NULL:
- return "QOS-NULL";
- case WLAN_FC_STYPE_QOS_CFPOLL:
- return "QOS-CFPOLL";
- case WLAN_FC_STYPE_QOS_CFACKPOLL:
- return "QOS-CFACKPOLL";
- }
- return "??";
-}
-
-
-static void rx_data_eth(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr, const u8 *dst, const u8 *src,
- u16 ethertype, const u8 *data, size_t len, int prot,
- const u8 *peer_addr)
-{
- switch (ethertype) {
- case ETH_P_PAE:
- rx_data_eapol(wt, dst, src, data, len, prot);
- break;
- case ETH_P_IP:
- rx_data_ip(wt, bssid, sta_addr, dst, src, data, len,
- peer_addr);
- break;
- case 0x890d:
- rx_data_80211_encap(wt, bssid, sta_addr, dst, src, data, len);
- break;
- }
-}
-
-
-static void rx_data_process(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr,
- const u8 *dst, const u8 *src,
- const u8 *data, size_t len, int prot,
- const u8 *peer_addr)
-{
- if (len == 0)
- return;
-
- if (len >= 8 && os_memcmp(data, "\xaa\xaa\x03\x00\x00\x00", 6) == 0) {
- rx_data_eth(wt, bssid, sta_addr, dst, src,
- WPA_GET_BE16(data + 6), data + 8, len - 8, prot,
- peer_addr);
- return;
- }
-
- wpa_hexdump(MSG_DEBUG, "Unrecognized LLC", data, len > 8 ? 8 : len);
-}
-
-
-static void rx_data_bss_prot_group(struct wlantest *wt,
- const struct ieee80211_hdr *hdr,
- const u8 *qos, const u8 *dst, const u8 *src,
- const u8 *data, size_t len)
-{
- struct wlantest_bss *bss;
- int keyid;
- u8 *decrypted;
- size_t dlen;
- u8 pn[6];
-
- bss = bss_get(wt, hdr->addr2);
- if (bss == NULL)
- return;
- if (len < 4) {
- wpa_printf(MSG_INFO, "Too short group addressed data frame");
- return;
- }
-
- if (bss->group_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
- !(data[3] & 0x20)) {
- wpa_printf(MSG_INFO, "Expected TKIP/CCMP frame from "
- MACSTR " did not have ExtIV bit set to 1",
- MAC2STR(bss->bssid));
- return;
- }
-
- if (bss->group_cipher == WPA_CIPHER_TKIP) {
- if (data[3] & 0x1f) {
- wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
- "non-zero reserved bit",
- MAC2STR(bss->bssid));
- }
- if (data[1] != ((data[0] | 0x20) & 0x7f)) {
- wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
- "incorrect WEPSeed[1] (was 0x%x, expected "
- "0x%x)",
- MAC2STR(bss->bssid), data[1],
- (data[0] | 0x20) & 0x7f);
- }
- } else if (bss->group_cipher == WPA_CIPHER_CCMP) {
- if (data[2] != 0 || (data[3] & 0x1f) != 0) {
- wpa_printf(MSG_INFO, "CCMP frame from " MACSTR " used "
- "non-zero reserved bit",
- MAC2STR(bss->bssid));
- }
- }
-
- keyid = data[3] >> 6;
- if (bss->gtk_len[keyid] == 0 && bss->group_cipher != WPA_CIPHER_WEP40)
- {
- wpa_printf(MSG_MSGDUMP, "No GTK known to decrypt the frame "
- "(A2=" MACSTR " KeyID=%d)",
- MAC2STR(hdr->addr2), keyid);
- return;
- }
-
- if (bss->group_cipher == WPA_CIPHER_TKIP)
- tkip_get_pn(pn, data);
- else if (bss->group_cipher == WPA_CIPHER_WEP40)
- goto skip_replay_det;
- else
- ccmp_get_pn(pn, data);
- if (os_memcmp(pn, bss->rsc[keyid], 6) <= 0) {
- u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
- wpa_printf(MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
- " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
- MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3),
- WLAN_GET_SEQ_SEQ(seq_ctrl),
- WLAN_GET_SEQ_FRAG(seq_ctrl));
- wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
- wpa_hexdump(MSG_INFO, "RSC", bss->rsc[keyid], 6);
- }
-
-skip_replay_det:
- if (bss->group_cipher == WPA_CIPHER_TKIP)
- decrypted = tkip_decrypt(bss->gtk[keyid], hdr, data, len,
- &dlen);
- else if (bss->group_cipher == WPA_CIPHER_WEP40)
- decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
- else
- decrypted = ccmp_decrypt(bss->gtk[keyid], hdr, data, len,
- &dlen);
- if (decrypted) {
- rx_data_process(wt, bss->bssid, NULL, dst, src, decrypted,
- dlen, 1, NULL);
- os_memcpy(bss->rsc[keyid], pn, 6);
- write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
- decrypted, dlen);
- }
- os_free(decrypted);
-}
-
-
-static void rx_data_bss_prot(struct wlantest *wt,
- const struct ieee80211_hdr *hdr, const u8 *qos,
- const u8 *dst, const u8 *src, const u8 *data,
- size_t len)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta, *sta2;
- int keyid;
- u16 fc = le_to_host16(hdr->frame_control);
- u8 *decrypted;
- size_t dlen;
- int tid;
- u8 pn[6], *rsc;
- struct wlantest_tdls *tdls = NULL;
- const u8 *tk = NULL;
-
- if (hdr->addr1[0] & 0x01) {
- rx_data_bss_prot_group(wt, hdr, qos, dst, src, data, len);
- return;
- }
-
- if (fc & WLAN_FC_TODS) {
- bss = bss_get(wt, hdr->addr1);
- if (bss == NULL)
- return;
- sta = sta_get(bss, hdr->addr2);
- if (sta)
- sta->counters[WLANTEST_STA_COUNTER_PROT_DATA_TX]++;
- } else if (fc & WLAN_FC_FROMDS) {
- bss = bss_get(wt, hdr->addr2);
- if (bss == NULL)
- return;
- sta = sta_get(bss, hdr->addr1);
- } else {
- bss = bss_get(wt, hdr->addr3);
- if (bss == NULL)
- return;
- sta = sta_find(bss, hdr->addr2);
- sta2 = sta_find(bss, hdr->addr1);
- if (sta == NULL || sta2 == NULL)
- return;
- dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list)
- {
- if ((tdls->init == sta && tdls->resp == sta2) ||
- (tdls->init == sta2 && tdls->resp == sta)) {
- if (!tdls->link_up)
- wpa_printf(MSG_DEBUG, "TDLS: Link not "
- "up, but Data frame seen");
- tk = tdls->tpk.tk;
- break;
- }
- }
- }
- if ((sta == NULL ||
- (!sta->ptk_set && sta->pairwise_cipher != WPA_CIPHER_WEP40)) &&
- tk == NULL) {
- wpa_printf(MSG_MSGDUMP, "No PTK known to decrypt the frame");
- return;
- }
-
- if (len < 4) {
- wpa_printf(MSG_INFO, "Too short encrypted data frame");
- return;
- }
-
- if (sta->pairwise_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP) &&
- !(data[3] & 0x20)) {
- wpa_printf(MSG_INFO, "Expected TKIP/CCMP frame from "
- MACSTR " did not have ExtIV bit set to 1",
- MAC2STR(src));
- return;
- }
-
- if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP) {
- if (data[3] & 0x1f) {
- wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
- "non-zero reserved bit",
- MAC2STR(hdr->addr2));
- }
- if (data[1] != ((data[0] | 0x20) & 0x7f)) {
- wpa_printf(MSG_INFO, "TKIP frame from " MACSTR " used "
- "incorrect WEPSeed[1] (was 0x%x, expected "
- "0x%x)",
- MAC2STR(hdr->addr2), data[1],
- (data[0] | 0x20) & 0x7f);
- }
- } else if (tk || sta->pairwise_cipher == WPA_CIPHER_CCMP) {
- if (data[2] != 0 || (data[3] & 0x1f) != 0) {
- wpa_printf(MSG_INFO, "CCMP frame from " MACSTR " used "
- "non-zero reserved bit",
- MAC2STR(hdr->addr2));
- }
- }
-
- keyid = data[3] >> 6;
- if (keyid != 0) {
- wpa_printf(MSG_INFO, "Unexpected non-zero KeyID %d in "
- "individually addressed Data frame from " MACSTR,
- keyid, MAC2STR(hdr->addr2));
- }
-
- if (qos)
- tid = qos[0] & 0x0f;
- else
- tid = 0;
- if (tk) {
- if (os_memcmp(hdr->addr2, tdls->init->addr, ETH_ALEN) == 0)
- rsc = tdls->rsc_init[tid];
- else
- rsc = tdls->rsc_resp[tid];
- } else if (fc & WLAN_FC_TODS)
- rsc = sta->rsc_tods[tid];
- else
- rsc = sta->rsc_fromds[tid];
-
-
- if (tk == NULL && sta->pairwise_cipher == WPA_CIPHER_TKIP)
- tkip_get_pn(pn, data);
- else if (sta->pairwise_cipher == WPA_CIPHER_WEP40)
- goto skip_replay_det;
- else
- ccmp_get_pn(pn, data);
- if (os_memcmp(pn, rsc, 6) <= 0) {
- u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
- wpa_printf(MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
- " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
- MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3),
- WLAN_GET_SEQ_SEQ(seq_ctrl),
- WLAN_GET_SEQ_FRAG(seq_ctrl));
- wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
- wpa_hexdump(MSG_INFO, "RSC", rsc, 6);
- }
-
-skip_replay_det:
- if (tk)
- decrypted = ccmp_decrypt(tk, hdr, data, len, &dlen);
- else if (sta->pairwise_cipher == WPA_CIPHER_TKIP)
- decrypted = tkip_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
- else if (sta->pairwise_cipher == WPA_CIPHER_WEP40)
- decrypted = wep_decrypt(wt, hdr, data, len, &dlen);
- else
- decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data, len, &dlen);
- if (decrypted) {
- u16 fc = le_to_host16(hdr->frame_control);
- const u8 *peer_addr = NULL;
- if (!(fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)))
- peer_addr = hdr->addr1;
- os_memcpy(rsc, pn, 6);
- rx_data_process(wt, bss->bssid, sta->addr, dst, src, decrypted,
- dlen, 1, peer_addr);
- write_pcap_decrypted(wt, (const u8 *) hdr, 24 + (qos ? 2 : 0),
- decrypted, dlen);
- }
- os_free(decrypted);
-}
-
-
-static void rx_data_bss(struct wlantest *wt, const struct ieee80211_hdr *hdr,
- const u8 *qos, const u8 *dst, const u8 *src,
- const u8 *data, size_t len)
-{
- u16 fc = le_to_host16(hdr->frame_control);
- int prot = !!(fc & WLAN_FC_ISWEP);
-
- if (qos) {
- u8 ack = (qos[0] & 0x60) >> 5;
- wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
- " len=%u%s tid=%u%s%s",
- MAC2STR(src), MAC2STR(dst), (unsigned int) len,
- prot ? " Prot" : "", qos[0] & 0x0f,
- (qos[0] & 0x10) ? " EOSP" : "",
- ack == 0 ? "" :
- (ack == 1 ? " NoAck" :
- (ack == 2 ? " NoExpAck" : " BA")));
- } else {
- wpa_printf(MSG_MSGDUMP, "BSS DATA: " MACSTR " -> " MACSTR
- " len=%u%s",
- MAC2STR(src), MAC2STR(dst), (unsigned int) len,
- prot ? " Prot" : "");
- }
-
- if (prot)
- rx_data_bss_prot(wt, hdr, qos, dst, src, data, len);
- else {
- const u8 *bssid, *sta_addr, *peer_addr;
- if (fc & WLAN_FC_TODS) {
- bssid = hdr->addr1;
- sta_addr = hdr->addr2;
- peer_addr = NULL;
- } else if (fc & WLAN_FC_FROMDS) {
- bssid = hdr->addr2;
- sta_addr = hdr->addr1;
- peer_addr = NULL;
- } else {
- bssid = hdr->addr3;
- sta_addr = hdr->addr2;
- peer_addr = hdr->addr1;
- }
- rx_data_process(wt, bssid, sta_addr, dst, src, data, len, 0,
- peer_addr);
- }
-}
-
-
-static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *bssid,
- const u8 *sta1_addr,
- const u8 *sta2_addr)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta1, *sta2;
- struct wlantest_tdls *tdls;
-
- bss = bss_find(wt, bssid);
- if (bss == NULL)
- return NULL;
- sta1 = sta_find(bss, sta1_addr);
- if (sta1 == NULL)
- return NULL;
- sta2 = sta_find(bss, sta2_addr);
- if (sta2 == NULL)
- return NULL;
-
- dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
- if ((tdls->init == sta1 && tdls->resp == sta2) ||
- (tdls->init == sta2 && tdls->resp == sta1))
- return tdls;
- }
-
- return NULL;
-}
-
-
-static void add_direct_link(struct wlantest *wt, const u8 *bssid,
- const u8 *sta1_addr, const u8 *sta2_addr)
-{
- struct wlantest_tdls *tdls;
-
- tdls = get_tdls(wt, bssid, sta1_addr, sta2_addr);
- if (tdls == NULL)
- return;
-
- if (tdls->link_up)
- tdls->counters[WLANTEST_TDLS_COUNTER_VALID_DIRECT_LINK]++;
- else
- tdls->counters[WLANTEST_TDLS_COUNTER_INVALID_DIRECT_LINK]++;
-}
-
-
-static void add_ap_path(struct wlantest *wt, const u8 *bssid,
- const u8 *sta1_addr, const u8 *sta2_addr)
-{
- struct wlantest_tdls *tdls;
-
- tdls = get_tdls(wt, bssid, sta1_addr, sta2_addr);
- if (tdls == NULL)
- return;
-
- if (tdls->link_up)
- tdls->counters[WLANTEST_TDLS_COUNTER_INVALID_AP_PATH]++;
- else
- tdls->counters[WLANTEST_TDLS_COUNTER_VALID_AP_PATH]++;
-}
-
-
-void rx_data(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_hdr *hdr;
- u16 fc, stype;
- size_t hdrlen;
- const u8 *qos = NULL;
-
- if (len < 24)
- return;
-
- hdr = (const struct ieee80211_hdr *) data;
- fc = le_to_host16(hdr->frame_control);
- stype = WLAN_FC_GET_STYPE(fc);
- hdrlen = 24;
- if ((fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) ==
- (WLAN_FC_TODS | WLAN_FC_FROMDS))
- hdrlen += ETH_ALEN;
- if (stype & 0x08) {
- qos = data + hdrlen;
- hdrlen += 2;
- }
- if (len < hdrlen)
- return;
- wt->rx_data++;
-
- switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) {
- case 0:
- wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s IBSS DA=" MACSTR " SA="
- MACSTR " BSSID=" MACSTR,
- data_stype(WLAN_FC_GET_STYPE(fc)),
- fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
- fc & WLAN_FC_ISWEP ? " Prot" : "",
- MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3));
- add_direct_link(wt, hdr->addr3, hdr->addr1, hdr->addr2);
- rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr2,
- data + hdrlen, len - hdrlen);
- break;
- case WLAN_FC_FROMDS:
- wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s FromDS DA=" MACSTR
- " BSSID=" MACSTR " SA=" MACSTR,
- data_stype(WLAN_FC_GET_STYPE(fc)),
- fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
- fc & WLAN_FC_ISWEP ? " Prot" : "",
- MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3));
- add_ap_path(wt, hdr->addr2, hdr->addr1, hdr->addr3);
- rx_data_bss(wt, hdr, qos, hdr->addr1, hdr->addr3,
- data + hdrlen, len - hdrlen);
- break;
- case WLAN_FC_TODS:
- wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s ToDS BSSID=" MACSTR
- " SA=" MACSTR " DA=" MACSTR,
- data_stype(WLAN_FC_GET_STYPE(fc)),
- fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
- fc & WLAN_FC_ISWEP ? " Prot" : "",
- MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3));
- add_ap_path(wt, hdr->addr1, hdr->addr3, hdr->addr2);
- rx_data_bss(wt, hdr, qos, hdr->addr3, hdr->addr2,
- data + hdrlen, len - hdrlen);
- break;
- case WLAN_FC_TODS | WLAN_FC_FROMDS:
- wpa_printf(MSG_EXCESSIVE, "DATA %s%s%s WDS RA=" MACSTR " TA="
- MACSTR " DA=" MACSTR " SA=" MACSTR,
- data_stype(WLAN_FC_GET_STYPE(fc)),
- fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
- fc & WLAN_FC_ISWEP ? " Prot" : "",
- MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3),
- MAC2STR((const u8 *) (hdr + 1)));
- break;
- }
-}
diff --git a/wlantest/rx_eapol.c b/wlantest/rx_eapol.c
deleted file mode 100644
index ad9035f..0000000
--- a/wlantest/rx_eapol.c
+++ /dev/null
@@ -1,1034 +0,0 @@
-/*
- * Received Data frame processing for EAPOL messages
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "crypto/aes_wrap.h"
-#include "crypto/crypto.h"
-#include "common/defs.h"
-#include "common/ieee802_11_defs.h"
-#include "common/eapol_common.h"
-#include "common/wpa_common.h"
-#include "rsn_supp/wpa_ie.h"
-#include "wlantest.h"
-
-
-static int is_zero(const u8 *buf, size_t len)
-{
- size_t i;
- for (i = 0; i < len; i++) {
- if (buf[i])
- return 0;
- }
- return 1;
-}
-
-
-static int check_mic(const u8 *kck, int ver, const u8 *data, size_t len)
-{
- u8 *buf;
- int ret = -1;
- struct ieee802_1x_hdr *hdr;
- struct wpa_eapol_key *key;
- u8 rx_mic[16];
-
- buf = os_malloc(len);
- if (buf == NULL)
- return -1;
- os_memcpy(buf, data, len);
- hdr = (struct ieee802_1x_hdr *) buf;
- key = (struct wpa_eapol_key *) (hdr + 1);
-
- os_memcpy(rx_mic, key->key_mic, 16);
- os_memset(key->key_mic, 0, 16);
-
- if (wpa_eapol_key_mic(kck, ver, buf, len, key->key_mic) == 0 &&
- os_memcmp(rx_mic, key->key_mic, 16) == 0)
- ret = 0;
-
- os_free(buf);
-
- return ret;
-}
-
-
-static void rx_data_eapol_key_1_of_4(struct wlantest *wt, const u8 *dst,
- const u8 *src, const u8 *data, size_t len)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- const struct ieee802_1x_hdr *eapol;
- const struct wpa_eapol_key *hdr;
-
- wpa_printf(MSG_DEBUG, "EAPOL-Key 1/4 " MACSTR " -> " MACSTR,
- MAC2STR(src), MAC2STR(dst));
- bss = bss_get(wt, src);
- if (bss == NULL)
- return;
- sta = sta_get(bss, dst);
- if (sta == NULL)
- return;
-
- eapol = (const struct ieee802_1x_hdr *) data;
- hdr = (const struct wpa_eapol_key *) (eapol + 1);
- if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
- wpa_printf(MSG_INFO, "EAPOL-Key 1/4 from " MACSTR " used "
- "zero nonce", MAC2STR(src));
- }
- if (!is_zero(hdr->key_rsc, 8)) {
- wpa_printf(MSG_INFO, "EAPOL-Key 1/4 from " MACSTR " used "
- "non-zero Key RSC", MAC2STR(src));
- }
- os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
-}
-
-
-static int try_pmk(struct wlantest_bss *bss, struct wlantest_sta *sta,
- u16 ver, const u8 *data, size_t len,
- struct wlantest_pmk *pmk)
-{
- struct wpa_ptk ptk;
- size_t ptk_len = sta->pairwise_cipher == WPA_CIPHER_TKIP ? 64 : 48;
- wpa_pmk_to_ptk(pmk->pmk, sizeof(pmk->pmk),
- "Pairwise key expansion",
- bss->bssid, sta->addr, sta->anonce, sta->snonce,
- (u8 *) &ptk, ptk_len,
- wpa_key_mgmt_sha256(sta->key_mgmt));
- if (check_mic(ptk.kck, ver, data, len) < 0)
- return -1;
-
- wpa_printf(MSG_INFO, "Derived PTK for STA " MACSTR " BSSID " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- sta->counters[WLANTEST_STA_COUNTER_PTK_LEARNED]++;
- if (sta->ptk_set) {
- /*
- * Rekeying - use new PTK for EAPOL-Key frames, but continue
- * using the old PTK for frame decryption.
- */
- os_memcpy(&sta->tptk, &ptk, sizeof(ptk));
- wpa_hexdump(MSG_DEBUG, "TPTK:KCK", sta->tptk.kck, 16);
- wpa_hexdump(MSG_DEBUG, "TPTK:KEK", sta->tptk.kek, 16);
- wpa_hexdump(MSG_DEBUG, "TPTK:TK1", sta->tptk.tk1, 16);
- if (ptk_len > 48)
- wpa_hexdump(MSG_DEBUG, "TPTK:TK2", sta->tptk.u.tk2,
- 16);
- sta->tptk_set = 1;
- return 0;
- }
- os_memcpy(&sta->ptk, &ptk, sizeof(ptk));
- wpa_hexdump(MSG_DEBUG, "PTK:KCK", sta->ptk.kck, 16);
- wpa_hexdump(MSG_DEBUG, "PTK:KEK", sta->ptk.kek, 16);
- wpa_hexdump(MSG_DEBUG, "PTK:TK1", sta->ptk.tk1, 16);
- if (ptk_len > 48)
- wpa_hexdump(MSG_DEBUG, "PTK:TK2", sta->ptk.u.tk2, 16);
- sta->ptk_set = 1;
- os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
- os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
- return 0;
-}
-
-
-static void derive_ptk(struct wlantest *wt, struct wlantest_bss *bss,
- struct wlantest_sta *sta, u16 ver,
- const u8 *data, size_t len)
-{
- struct wlantest_pmk *pmk;
-
- wpa_printf(MSG_DEBUG, "Trying to derive PTK for " MACSTR,
- MAC2STR(sta->addr));
- dl_list_for_each(pmk, &bss->pmk, struct wlantest_pmk, list) {
- wpa_printf(MSG_DEBUG, "Try per-BSS PMK");
- if (try_pmk(bss, sta, ver, data, len, pmk) == 0)
- return;
- }
-
- dl_list_for_each(pmk, &wt->pmk, struct wlantest_pmk, list) {
- wpa_printf(MSG_DEBUG, "Try global PMK");
- if (try_pmk(bss, sta, ver, data, len, pmk) == 0)
- return;
- }
- wpa_printf(MSG_DEBUG, "No matching PMK found to derive PTK");
-}
-
-
-static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
- const u8 *src, const u8 *data, size_t len)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- const struct ieee802_1x_hdr *eapol;
- const struct wpa_eapol_key *hdr;
- const u8 *key_data, *kck;
- u16 key_info, key_data_len;
- struct wpa_eapol_ie_parse ie;
-
- wpa_printf(MSG_DEBUG, "EAPOL-Key 2/4 " MACSTR " -> " MACSTR,
- MAC2STR(src), MAC2STR(dst));
- bss = bss_get(wt, dst);
- if (bss == NULL)
- return;
- sta = sta_get(bss, src);
- if (sta == NULL)
- return;
-
- eapol = (const struct ieee802_1x_hdr *) data;
- hdr = (const struct wpa_eapol_key *) (eapol + 1);
- if (is_zero(hdr->key_nonce, WPA_NONCE_LEN)) {
- wpa_printf(MSG_INFO, "EAPOL-Key 2/4 from " MACSTR " used "
- "zero nonce", MAC2STR(src));
- }
- if (!is_zero(hdr->key_rsc, 8)) {
- wpa_printf(MSG_INFO, "EAPOL-Key 2/4 from " MACSTR " used "
- "non-zero Key RSC", MAC2STR(src));
- }
- os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
- key_info = WPA_GET_BE16(hdr->key_info);
- key_data_len = WPA_GET_BE16(hdr->key_data_length);
- derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
-
- if (!sta->ptk_set && !sta->tptk_set) {
- wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 2/4");
- return;
- }
-
- kck = sta->ptk.kck;
- if (sta->tptk_set) {
- wpa_printf(MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC");
- kck = sta->tptk.kck;
- }
- if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
- wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 2/4 MIC");
- return;
- }
- wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
-
- key_data = (const u8 *) (hdr + 1);
-
- if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
- wpa_printf(MSG_INFO, "Failed to parse EAPOL-Key Key Data");
- return;
- }
-
- if (ie.wpa_ie) {
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
- ie.wpa_ie, ie.wpa_ie_len);
- if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) {
- wpa_printf(MSG_INFO, "Mismatch in WPA IE between "
- "EAPOL-Key 2/4 and (Re)Association "
- "Request from " MACSTR, MAC2STR(sta->addr));
- wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
- ie.wpa_ie, ie.wpa_ie_len);
- wpa_hexdump(MSG_INFO, "WPA IE in (Re)Association "
- "Request",
- sta->rsnie,
- sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
- }
- }
-
- if (ie.rsn_ie) {
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
- ie.rsn_ie, ie.rsn_ie_len);
- if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) {
- wpa_printf(MSG_INFO, "Mismatch in RSN IE between "
- "EAPOL-Key 2/4 and (Re)Association "
- "Request from " MACSTR, MAC2STR(sta->addr));
- wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
- ie.rsn_ie, ie.rsn_ie_len);
- wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
- "Request",
- sta->rsnie,
- sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
- }
- }
-}
-
-
-static u8 * decrypt_eapol_key_data_rc4(const u8 *kek,
- const struct wpa_eapol_key *hdr,
- size_t *len)
-{
- u8 ek[32], *buf;
- u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
-
- buf = os_malloc(keydatalen);
- if (buf == NULL)
- return NULL;
-
- os_memcpy(ek, hdr->key_iv, 16);
- os_memcpy(ek + 16, kek, 16);
- os_memcpy(buf, hdr + 1, keydatalen);
- if (rc4_skip(ek, 32, 256, buf, keydatalen)) {
- wpa_printf(MSG_INFO, "RC4 failed");
- os_free(buf);
- return NULL;
- }
-
- *len = keydatalen;
- return buf;
-}
-
-
-static u8 * decrypt_eapol_key_data_aes(const u8 *kek,
- const struct wpa_eapol_key *hdr,
- size_t *len)
-{
- u8 *buf;
- u16 keydatalen = WPA_GET_BE16(hdr->key_data_length);
-
- if (keydatalen % 8) {
- wpa_printf(MSG_INFO, "Unsupported AES-WRAP len %d",
- keydatalen);
- return NULL;
- }
- keydatalen -= 8; /* AES-WRAP adds 8 bytes */
- buf = os_malloc(keydatalen);
- if (buf == NULL)
- return NULL;
- if (aes_unwrap(kek, keydatalen / 8, (u8 *) (hdr + 1), buf)) {
- os_free(buf);
- wpa_printf(MSG_INFO, "AES unwrap failed - "
- "could not decrypt EAPOL-Key key data");
- return NULL;
- }
-
- *len = keydatalen;
- return buf;
-}
-
-
-static u8 * decrypt_eapol_key_data(const u8 *kek, u16 ver,
- const struct wpa_eapol_key *hdr,
- size_t *len)
-{
- switch (ver) {
- case WPA_KEY_INFO_TYPE_HMAC_MD5_RC4:
- return decrypt_eapol_key_data_rc4(kek, hdr, len);
- case WPA_KEY_INFO_TYPE_HMAC_SHA1_AES:
- case WPA_KEY_INFO_TYPE_AES_128_CMAC:
- return decrypt_eapol_key_data_aes(kek, hdr, len);
- default:
- wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
- "Version %u", ver);
- return NULL;
- }
-}
-
-
-static void learn_kde_keys(struct wlantest_bss *bss, struct wlantest_sta *sta,
- const u8 *buf, size_t len, const u8 *rsc)
-{
- struct wpa_eapol_ie_parse ie;
-
- if (wpa_supplicant_parse_ies(buf, len, &ie) < 0) {
- wpa_printf(MSG_INFO, "Failed to parse EAPOL-Key Key Data");
- return;
- }
-
- if (ie.wpa_ie) {
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
- ie.wpa_ie, ie.wpa_ie_len);
- }
-
- if (ie.rsn_ie) {
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
- ie.rsn_ie, ie.rsn_ie_len);
- }
-
- if (ie.gtk) {
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - GTK KDE",
- ie.gtk, ie.gtk_len);
- if (ie.gtk_len >= 2 && ie.gtk_len <= 2 + 32) {
- int id;
- id = ie.gtk[0] & 0x03;
- wpa_printf(MSG_DEBUG, "GTK KeyID=%u tx=%u",
- id, !!(ie.gtk[0] & 0x04));
- if ((ie.gtk[0] & 0xf8) || ie.gtk[1])
- wpa_printf(MSG_INFO, "GTK KDE: Reserved field "
- "set: %02x %02x",
- ie.gtk[0], ie.gtk[1]);
- wpa_hexdump(MSG_DEBUG, "GTK", ie.gtk + 2,
- ie.gtk_len - 2);
- bss->gtk_len[id] = ie.gtk_len - 2;
- sta->gtk_len = ie.gtk_len - 2;
- os_memcpy(bss->gtk[id], ie.gtk + 2, ie.gtk_len - 2);
- os_memcpy(sta->gtk, ie.gtk + 2, ie.gtk_len - 2);
- bss->rsc[id][0] = rsc[5];
- bss->rsc[id][1] = rsc[4];
- bss->rsc[id][2] = rsc[3];
- bss->rsc[id][3] = rsc[2];
- bss->rsc[id][4] = rsc[1];
- bss->rsc[id][5] = rsc[0];
- bss->gtk_idx = id;
- sta->gtk_idx = id;
- wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
- } else {
- wpa_printf(MSG_INFO, "Invalid GTK KDE length %u",
- (unsigned) ie.gtk_len);
- }
- }
-
- if (ie.igtk) {
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - IGTK KDE",
- ie.igtk, ie.igtk_len);
- if (ie.igtk_len == 24) {
- u16 id;
- id = WPA_GET_LE16(ie.igtk);
- if (id > 5) {
- wpa_printf(MSG_INFO, "Unexpected IGTK KeyID "
- "%u", id);
- } else {
- const u8 *ipn;
- wpa_printf(MSG_DEBUG, "IGTK KeyID %u", id);
- wpa_hexdump(MSG_DEBUG, "IPN", ie.igtk + 2, 6);
- wpa_hexdump(MSG_DEBUG, "IGTK", ie.igtk + 8,
- 16);
- os_memcpy(bss->igtk[id], ie.igtk + 8, 16);
- bss->igtk_set[id] = 1;
- ipn = ie.igtk + 2;
- bss->ipn[id][0] = ipn[5];
- bss->ipn[id][1] = ipn[4];
- bss->ipn[id][2] = ipn[3];
- bss->ipn[id][3] = ipn[2];
- bss->ipn[id][4] = ipn[1];
- bss->ipn[id][5] = ipn[0];
- bss->igtk_idx = id;
- }
- } else {
- wpa_printf(MSG_INFO, "Invalid IGTK KDE length %u",
- (unsigned) ie.igtk_len);
- }
- }
-}
-
-
-static void rx_data_eapol_key_3_of_4(struct wlantest *wt, const u8 *dst,
- const u8 *src, const u8 *data, size_t len)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- const struct ieee802_1x_hdr *eapol;
- const struct wpa_eapol_key *hdr;
- const u8 *key_data, *kck, *kek;
- int recalc = 0;
- u16 key_info, ver;
- u8 *decrypted_buf = NULL;
- const u8 *decrypted;
- size_t decrypted_len = 0;
- struct wpa_eapol_ie_parse ie;
-
- wpa_printf(MSG_DEBUG, "EAPOL-Key 3/4 " MACSTR " -> " MACSTR,
- MAC2STR(src), MAC2STR(dst));
- bss = bss_get(wt, src);
- if (bss == NULL)
- return;
- sta = sta_get(bss, dst);
- if (sta == NULL)
- return;
-
- eapol = (const struct ieee802_1x_hdr *) data;
- hdr = (const struct wpa_eapol_key *) (eapol + 1);
- key_info = WPA_GET_BE16(hdr->key_info);
-
- if (os_memcmp(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN) != 0) {
- wpa_printf(MSG_INFO, "EAPOL-Key ANonce mismatch between 1/4 "
- "and 3/4");
- recalc = 1;
- }
- os_memcpy(sta->anonce, hdr->key_nonce, WPA_NONCE_LEN);
- if (recalc) {
- derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK,
- data, len);
- }
-
- if (!sta->ptk_set && !sta->tptk_set) {
- wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 3/4");
- return;
- }
-
- kek = sta->ptk.kek;
- kck = sta->ptk.kck;
- if (sta->tptk_set) {
- wpa_printf(MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC");
- kck = sta->tptk.kck;
- kek = sta->tptk.kek;
- }
- if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
- wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 3/4 MIC");
- return;
- }
- wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 3/4");
-
- key_data = (const u8 *) (hdr + 1);
- if (!(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
- if (sta->proto & WPA_PROTO_RSN)
- wpa_printf(MSG_INFO, "EAPOL-Key 3/4 without "
- "EncrKeyData bit");
- decrypted = key_data;
- decrypted_len = WPA_GET_BE16(hdr->key_data_length);
- } else {
- ver = key_info & WPA_KEY_INFO_TYPE_MASK;
- decrypted_buf = decrypt_eapol_key_data(kek, ver, hdr,
- &decrypted_len);
- if (decrypted_buf == NULL) {
- wpa_printf(MSG_INFO, "Failed to decrypt EAPOL-Key Key "
- "Data");
- return;
- }
- decrypted = decrypted_buf;
- wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
- decrypted, decrypted_len);
- }
- if (wt->write_pcap_dumper && decrypted != key_data) {
- /* Fill in a dummy Data frame header */
- u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
- struct ieee80211_hdr *h;
- struct wpa_eapol_key *k;
- const u8 *p;
- u8 *pos;
- size_t plain_len;
-
- plain_len = decrypted_len;
- p = decrypted;
- while (p + 1 < decrypted + decrypted_len) {
- if (p[0] == 0xdd && p[1] == 0x00) {
- /* Remove padding */
- plain_len = p - decrypted;
- break;
- }
- p += 2 + p[1];
- }
-
- os_memset(buf, 0, sizeof(buf));
- h = (struct ieee80211_hdr *) buf;
- h->frame_control = host_to_le16(0x0208);
- os_memcpy(h->addr1, dst, ETH_ALEN);
- os_memcpy(h->addr2, src, ETH_ALEN);
- os_memcpy(h->addr3, src, ETH_ALEN);
- pos = (u8 *) (h + 1);
- os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
- pos += 8;
- os_memcpy(pos, eapol, sizeof(*eapol));
- pos += sizeof(*eapol);
- os_memcpy(pos, hdr, sizeof(*hdr));
- k = (struct wpa_eapol_key *) pos;
- WPA_PUT_BE16(k->key_info,
- key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
- WPA_PUT_BE16(k->key_data_length, plain_len);
- write_pcap_decrypted(wt, buf, sizeof(buf),
- decrypted, plain_len);
- }
-
- if (wpa_supplicant_parse_ies(decrypted, decrypted_len, &ie) < 0) {
- wpa_printf(MSG_INFO, "Failed to parse EAPOL-Key Key Data");
- os_free(decrypted_buf);
- return;
- }
-
- if ((ie.wpa_ie &&
- os_memcmp(ie.wpa_ie, bss->wpaie, ie.wpa_ie_len) != 0) ||
- (ie.wpa_ie == NULL && bss->wpaie[0])) {
- wpa_printf(MSG_INFO, "Mismatch in WPA IE between "
- "EAPOL-Key 3/4 and Beacon/Probe Response "
- "from " MACSTR, MAC2STR(bss->bssid));
- wpa_hexdump(MSG_INFO, "WPA IE in EAPOL-Key",
- ie.wpa_ie, ie.wpa_ie_len);
- wpa_hexdump(MSG_INFO, "WPA IE in Beacon/Probe "
- "Response",
- bss->wpaie,
- bss->wpaie[0] ? 2 + bss->wpaie[1] : 0);
- }
-
- if ((ie.rsn_ie &&
- os_memcmp(ie.rsn_ie, bss->rsnie, ie.rsn_ie_len) != 0) ||
- (ie.rsn_ie == NULL && bss->rsnie[0])) {
- wpa_printf(MSG_INFO, "Mismatch in RSN IE between "
- "EAPOL-Key 3/4 and Beacon/Probe Response "
- "from " MACSTR, MAC2STR(bss->bssid));
- wpa_hexdump(MSG_INFO, "RSN IE in EAPOL-Key",
- ie.rsn_ie, ie.rsn_ie_len);
- wpa_hexdump(MSG_INFO, "RSN IE in (Re)Association "
- "Request",
- bss->rsnie,
- bss->rsnie[0] ? 2 + bss->rsnie[1] : 0);
- }
-
- learn_kde_keys(bss, sta, decrypted, decrypted_len, hdr->key_rsc);
- os_free(decrypted_buf);
-}
-
-
-static void rx_data_eapol_key_4_of_4(struct wlantest *wt, const u8 *dst,
- const u8 *src, const u8 *data, size_t len)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- const struct ieee802_1x_hdr *eapol;
- const struct wpa_eapol_key *hdr;
- u16 key_info;
- const u8 *kck;
-
- wpa_printf(MSG_DEBUG, "EAPOL-Key 4/4 " MACSTR " -> " MACSTR,
- MAC2STR(src), MAC2STR(dst));
- bss = bss_get(wt, dst);
- if (bss == NULL)
- return;
- sta = sta_get(bss, src);
- if (sta == NULL)
- return;
-
- eapol = (const struct ieee802_1x_hdr *) data;
- hdr = (const struct wpa_eapol_key *) (eapol + 1);
- if (!is_zero(hdr->key_rsc, 8)) {
- wpa_printf(MSG_INFO, "EAPOL-Key 4/4 from " MACSTR " used "
- "non-zero Key RSC", MAC2STR(src));
- }
- key_info = WPA_GET_BE16(hdr->key_info);
-
- if (!sta->ptk_set && !sta->tptk_set) {
- wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 4/4");
- return;
- }
-
- kck = sta->ptk.kck;
- if (sta->tptk_set) {
- wpa_printf(MSG_DEBUG, "Use TPTK for validation EAPOL-Key MIC");
- kck = sta->tptk.kck;
- }
- if (check_mic(kck, key_info & WPA_KEY_INFO_TYPE_MASK, data, len) < 0) {
- wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 4/4 MIC");
- return;
- }
- wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 4/4");
- if (sta->tptk_set) {
- wpa_printf(MSG_DEBUG, "Update PTK (rekeying)");
- os_memcpy(&sta->ptk, &sta->tptk, sizeof(sta->ptk));
- sta->ptk_set = 1;
- sta->tptk_set = 0;
- os_memset(sta->rsc_tods, 0, sizeof(sta->rsc_tods));
- os_memset(sta->rsc_fromds, 0, sizeof(sta->rsc_fromds));
- }
-}
-
-
-static void rx_data_eapol_key_1_of_2(struct wlantest *wt, const u8 *dst,
- const u8 *src, const u8 *data, size_t len)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- const struct ieee802_1x_hdr *eapol;
- const struct wpa_eapol_key *hdr;
- const u8 *key_data;
- u16 key_info, ver;
- u8 *decrypted;
- size_t decrypted_len = 0;
-
- wpa_printf(MSG_DEBUG, "EAPOL-Key 1/2 " MACSTR " -> " MACSTR,
- MAC2STR(src), MAC2STR(dst));
- bss = bss_get(wt, src);
- if (bss == NULL)
- return;
- sta = sta_get(bss, dst);
- if (sta == NULL)
- return;
-
- eapol = (const struct ieee802_1x_hdr *) data;
- hdr = (const struct wpa_eapol_key *) (eapol + 1);
- key_info = WPA_GET_BE16(hdr->key_info);
-
- if (!sta->ptk_set) {
- wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 1/2");
- return;
- }
-
- if (sta->ptk_set &&
- check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
- data, len) < 0) {
- wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 1/2 MIC");
- return;
- }
- wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 1/2");
-
- key_data = (const u8 *) (hdr + 1);
- if (sta->proto & WPA_PROTO_RSN &&
- !(key_info & WPA_KEY_INFO_ENCR_KEY_DATA)) {
- wpa_printf(MSG_INFO, "EAPOL-Key 1/2 without EncrKeyData bit");
- return;
- }
- ver = key_info & WPA_KEY_INFO_TYPE_MASK;
- decrypted = decrypt_eapol_key_data(sta->ptk.kek, ver, hdr,
- &decrypted_len);
- if (decrypted == NULL) {
- wpa_printf(MSG_INFO, "Failed to decrypt EAPOL-Key Key Data");
- return;
- }
- wpa_hexdump(MSG_DEBUG, "Decrypted EAPOL-Key Key Data",
- decrypted, decrypted_len);
- if (wt->write_pcap_dumper) {
- /* Fill in a dummy Data frame header */
- u8 buf[24 + 8 + sizeof(*eapol) + sizeof(*hdr)];
- struct ieee80211_hdr *h;
- struct wpa_eapol_key *k;
- u8 *pos;
- size_t plain_len;
-
- plain_len = decrypted_len;
- pos = decrypted;
- while (pos + 1 < decrypted + decrypted_len) {
- if (pos[0] == 0xdd && pos[1] == 0x00) {
- /* Remove padding */
- plain_len = pos - decrypted;
- break;
- }
- pos += 2 + pos[1];
- }
-
- os_memset(buf, 0, sizeof(buf));
- h = (struct ieee80211_hdr *) buf;
- h->frame_control = host_to_le16(0x0208);
- os_memcpy(h->addr1, dst, ETH_ALEN);
- os_memcpy(h->addr2, src, ETH_ALEN);
- os_memcpy(h->addr3, src, ETH_ALEN);
- pos = (u8 *) (h + 1);
- os_memcpy(pos, "\xaa\xaa\x03\x00\x00\x00\x88\x8e", 8);
- pos += 8;
- os_memcpy(pos, eapol, sizeof(*eapol));
- pos += sizeof(*eapol);
- os_memcpy(pos, hdr, sizeof(*hdr));
- k = (struct wpa_eapol_key *) pos;
- WPA_PUT_BE16(k->key_info,
- key_info & ~WPA_KEY_INFO_ENCR_KEY_DATA);
- WPA_PUT_BE16(k->key_data_length, plain_len);
- write_pcap_decrypted(wt, buf, sizeof(buf),
- decrypted, plain_len);
- }
- if (sta->proto & WPA_PROTO_RSN)
- learn_kde_keys(bss, sta, decrypted, decrypted_len,
- hdr->key_rsc);
- else {
- int klen = bss->group_cipher == WPA_CIPHER_TKIP ? 32 : 16;
- if (decrypted_len == klen) {
- const u8 *rsc = hdr->key_rsc;
- int id;
- id = (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
- WPA_KEY_INFO_KEY_INDEX_SHIFT;
- wpa_printf(MSG_DEBUG, "GTK key index %d", id);
- wpa_hexdump(MSG_DEBUG, "GTK", decrypted,
- decrypted_len);
- bss->gtk_len[id] = decrypted_len;
- os_memcpy(bss->gtk[id], decrypted, decrypted_len);
- bss->rsc[id][0] = rsc[5];
- bss->rsc[id][1] = rsc[4];
- bss->rsc[id][2] = rsc[3];
- bss->rsc[id][3] = rsc[2];
- bss->rsc[id][4] = rsc[1];
- bss->rsc[id][5] = rsc[0];
- wpa_hexdump(MSG_DEBUG, "RSC", bss->rsc[id], 6);
- } else {
- wpa_printf(MSG_INFO, "Unexpected WPA Key Data length "
- "in Group Key msg 1/2 from " MACSTR,
- MAC2STR(src));
- }
- }
- os_free(decrypted);
-}
-
-
-static void rx_data_eapol_key_2_of_2(struct wlantest *wt, const u8 *dst,
- const u8 *src, const u8 *data, size_t len)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- const struct ieee802_1x_hdr *eapol;
- const struct wpa_eapol_key *hdr;
- u16 key_info;
-
- wpa_printf(MSG_DEBUG, "EAPOL-Key 2/2 " MACSTR " -> " MACSTR,
- MAC2STR(src), MAC2STR(dst));
- bss = bss_get(wt, dst);
- if (bss == NULL)
- return;
- sta = sta_get(bss, src);
- if (sta == NULL)
- return;
-
- eapol = (const struct ieee802_1x_hdr *) data;
- hdr = (const struct wpa_eapol_key *) (eapol + 1);
- if (!is_zero(hdr->key_rsc, 8)) {
- wpa_printf(MSG_INFO, "EAPOL-Key 2/2 from " MACSTR " used "
- "non-zero Key RSC", MAC2STR(src));
- }
- key_info = WPA_GET_BE16(hdr->key_info);
-
- if (!sta->ptk_set) {
- wpa_printf(MSG_DEBUG, "No PTK known to process EAPOL-Key 2/2");
- return;
- }
-
- if (sta->ptk_set &&
- check_mic(sta->ptk.kck, key_info & WPA_KEY_INFO_TYPE_MASK,
- data, len) < 0) {
- wpa_printf(MSG_INFO, "Mismatch in EAPOL-Key 2/2 MIC");
- return;
- }
- wpa_printf(MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/2");
-}
-
-
-static void rx_data_eapol_key(struct wlantest *wt, const u8 *dst,
- const u8 *src, const u8 *data, size_t len,
- int prot)
-{
- const struct ieee802_1x_hdr *eapol;
- const struct wpa_eapol_key *hdr;
- const u8 *key_data;
- u16 key_info, key_length, ver, key_data_length;
-
- eapol = (const struct ieee802_1x_hdr *) data;
- hdr = (const struct wpa_eapol_key *) (eapol + 1);
-
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key",
- (const u8 *) hdr, len - sizeof(*eapol));
- if (len < sizeof(*hdr)) {
- wpa_printf(MSG_INFO, "Too short EAPOL-Key frame from " MACSTR,
- MAC2STR(src));
- return;
- }
-
- if (hdr->type == EAPOL_KEY_TYPE_RC4) {
- /* TODO: EAPOL-Key RC4 for WEP */
- wpa_printf(MSG_INFO, "EAPOL-Key Descriptor Type RC4 from "
- MACSTR, MAC2STR(src));
- return;
- }
-
- if (hdr->type != EAPOL_KEY_TYPE_RSN &&
- hdr->type != EAPOL_KEY_TYPE_WPA) {
- wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Descriptor Type "
- "%u from " MACSTR, hdr->type, MAC2STR(src));
- return;
- }
-
- key_info = WPA_GET_BE16(hdr->key_info);
- key_length = WPA_GET_BE16(hdr->key_length);
- key_data_length = WPA_GET_BE16(hdr->key_data_length);
- key_data = (const u8 *) (hdr + 1);
- if (key_data + key_data_length > data + len) {
- wpa_printf(MSG_INFO, "Truncated EAPOL-Key from " MACSTR,
- MAC2STR(src));
- return;
- }
- if (key_data + key_data_length < data + len) {
- wpa_hexdump(MSG_DEBUG, "Extra data after EAPOL-Key Key Data "
- "field", key_data + key_data_length,
- data + len - key_data - key_data_length);
- }
-
-
- ver = key_info & WPA_KEY_INFO_TYPE_MASK;
- wpa_printf(MSG_DEBUG, "EAPOL-Key ver=%u %c idx=%u%s%s%s%s%s%s%s%s "
- "datalen=%u",
- ver, key_info & WPA_KEY_INFO_KEY_TYPE ? 'P' : 'G',
- (key_info & WPA_KEY_INFO_KEY_INDEX_MASK) >>
- WPA_KEY_INFO_KEY_INDEX_SHIFT,
- (key_info & WPA_KEY_INFO_INSTALL) ? " Install" : "",
- (key_info & WPA_KEY_INFO_ACK) ? " ACK" : "",
- (key_info & WPA_KEY_INFO_MIC) ? " MIC" : "",
- (key_info & WPA_KEY_INFO_SECURE) ? " Secure" : "",
- (key_info & WPA_KEY_INFO_ERROR) ? " Error" : "",
- (key_info & WPA_KEY_INFO_REQUEST) ? " Request" : "",
- (key_info & WPA_KEY_INFO_ENCR_KEY_DATA) ? " Encr" : "",
- (key_info & WPA_KEY_INFO_SMK_MESSAGE) ? " SMK" : "",
- key_data_length);
-
- if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
- ver != WPA_KEY_INFO_TYPE_HMAC_SHA1_AES &&
- ver != WPA_KEY_INFO_TYPE_AES_128_CMAC) {
- wpa_printf(MSG_INFO, "Unsupported EAPOL-Key Key Descriptor "
- "Version %u from " MACSTR, ver, MAC2STR(src));
- return;
- }
-
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Replay Counter",
- hdr->replay_counter, WPA_REPLAY_COUNTER_LEN);
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Nonce",
- hdr->key_nonce, WPA_NONCE_LEN);
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key IV",
- hdr->key_iv, 16);
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key RSC",
- hdr->key_rsc, WPA_KEY_RSC_LEN);
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key MIC",
- hdr->key_mic, 16);
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data",
- key_data, key_data_length);
-
- if (hdr->type == EAPOL_KEY_TYPE_RSN &&
- (key_info & (WPA_KEY_INFO_KEY_INDEX_MASK | BIT(14) | BIT(15))) !=
- 0) {
- wpa_printf(MSG_INFO, "RSN EAPOL-Key with non-zero reserved "
- "Key Info bits 0x%x from " MACSTR,
- key_info, MAC2STR(src));
- }
-
- if (hdr->type == EAPOL_KEY_TYPE_WPA &&
- (key_info & (WPA_KEY_INFO_ENCR_KEY_DATA |
- WPA_KEY_INFO_SMK_MESSAGE |BIT(14) | BIT(15))) != 0) {
- wpa_printf(MSG_INFO, "WPA EAPOL-Key with non-zero reserved "
- "Key Info bits 0x%x from " MACSTR,
- key_info, MAC2STR(src));
- }
-
- if (key_length > 32) {
- wpa_printf(MSG_INFO, "EAPOL-Key with invalid Key Length %d "
- "from " MACSTR, key_length, MAC2STR(src));
- }
-
- if (ver != WPA_KEY_INFO_TYPE_HMAC_MD5_RC4 &&
- !is_zero(hdr->key_iv, 16)) {
- wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key IV "
- "(reserved with ver=%d) field from " MACSTR,
- ver, MAC2STR(src));
- wpa_hexdump(MSG_INFO, "EAPOL-Key Key IV (reserved)",
- hdr->key_iv, 16);
- }
-
- if (!is_zero(hdr->key_id, 8)) {
- wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key ID "
- "(reserved) field from " MACSTR, MAC2STR(src));
- wpa_hexdump(MSG_INFO, "EAPOL-Key Key ID (reserved)",
- hdr->key_id, 8);
- }
-
- if (hdr->key_rsc[6] || hdr->key_rsc[7]) {
- wpa_printf(MSG_INFO, "EAPOL-Key with non-zero Key RSC octets "
- "(last two are unused)" MACSTR, MAC2STR(src));
- }
-
- if (key_info & (WPA_KEY_INFO_ERROR | WPA_KEY_INFO_REQUEST))
- return;
-
- if (key_info & WPA_KEY_INFO_SMK_MESSAGE)
- return;
-
- if (key_info & WPA_KEY_INFO_KEY_TYPE) {
- /* 4-Way Handshake */
- switch (key_info & (WPA_KEY_INFO_SECURE |
- WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_ACK |
- WPA_KEY_INFO_INSTALL)) {
- case WPA_KEY_INFO_ACK:
- rx_data_eapol_key_1_of_4(wt, dst, src, data, len);
- break;
- case WPA_KEY_INFO_MIC:
- if (key_data_length == 0)
- rx_data_eapol_key_4_of_4(wt, dst, src, data,
- len);
- else
- rx_data_eapol_key_2_of_4(wt, dst, src, data,
- len);
- break;
- case WPA_KEY_INFO_MIC | WPA_KEY_INFO_ACK |
- WPA_KEY_INFO_INSTALL:
- /* WPA does not include Secure bit in 3/4 */
- rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
- break;
- case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_ACK | WPA_KEY_INFO_INSTALL:
- rx_data_eapol_key_3_of_4(wt, dst, src, data, len);
- break;
- case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
- if (key_data_length == 0)
- rx_data_eapol_key_4_of_4(wt, dst, src, data,
- len);
- else
- rx_data_eapol_key_2_of_4(wt, dst, src, data,
- len);
- break;
- default:
- wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
- break;
- }
- } else {
- /* Group Key Handshake */
- switch (key_info & (WPA_KEY_INFO_SECURE |
- WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_ACK)) {
- case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC |
- WPA_KEY_INFO_ACK:
- rx_data_eapol_key_1_of_2(wt, dst, src, data, len);
- break;
- case WPA_KEY_INFO_SECURE | WPA_KEY_INFO_MIC:
- rx_data_eapol_key_2_of_2(wt, dst, src, data, len);
- break;
- default:
- wpa_printf(MSG_DEBUG, "Unsupported EAPOL-Key frame");
- break;
- }
- }
-}
-
-
-void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
- const u8 *data, size_t len, int prot)
-{
- const struct ieee802_1x_hdr *hdr;
- u16 length;
- const u8 *p;
-
- wpa_hexdump(MSG_EXCESSIVE, "EAPOL", data, len);
- if (len < sizeof(*hdr)) {
- wpa_printf(MSG_INFO, "Too short EAPOL frame from " MACSTR,
- MAC2STR(src));
- return;
- }
-
- hdr = (const struct ieee802_1x_hdr *) data;
- length = be_to_host16(hdr->length);
- wpa_printf(MSG_DEBUG, "RX EAPOL: " MACSTR " -> " MACSTR "%s ver=%u "
- "type=%u len=%u",
- MAC2STR(src), MAC2STR(dst), prot ? " Prot" : "",
- hdr->version, hdr->type, length);
- if (hdr->version < 1 || hdr->version > 3) {
- wpa_printf(MSG_INFO, "Unexpected EAPOL version %u from "
- MACSTR, hdr->version, MAC2STR(src));
- }
- if (sizeof(*hdr) + length > len) {
- wpa_printf(MSG_INFO, "Truncated EAPOL frame from " MACSTR,
- MAC2STR(src));
- return;
- }
-
- if (sizeof(*hdr) + length < len) {
- wpa_printf(MSG_INFO, "EAPOL frame with %d extra bytes",
- (int) (len - sizeof(*hdr) - length));
- }
- p = (const u8 *) (hdr + 1);
-
- switch (hdr->type) {
- case IEEE802_1X_TYPE_EAP_PACKET:
- wpa_hexdump(MSG_MSGDUMP, "EAPOL - EAP packet", p, length);
- break;
- case IEEE802_1X_TYPE_EAPOL_START:
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Start", p, length);
- break;
- case IEEE802_1X_TYPE_EAPOL_LOGOFF:
- wpa_hexdump(MSG_MSGDUMP, "EAPOL-Logoff", p, length);
- break;
- case IEEE802_1X_TYPE_EAPOL_KEY:
- rx_data_eapol_key(wt, dst, src, data, sizeof(*hdr) + length,
- prot);
- break;
- case IEEE802_1X_TYPE_EAPOL_ENCAPSULATED_ASF_ALERT:
- wpa_hexdump(MSG_MSGDUMP, "EAPOL - Encapsulated ASF alert",
- p, length);
- break;
- default:
- wpa_hexdump(MSG_MSGDUMP, "Unknown EAPOL payload", p, length);
- break;
- }
-}
diff --git a/wlantest/rx_ip.c b/wlantest/rx_ip.c
deleted file mode 100644
index 016004d..0000000
--- a/wlantest/rx_ip.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Received Data frame processing for IPv4 packets
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-
-#include "utils/common.h"
-#include "wlantest.h"
-
-
-static void ping_update(struct wlantest_sta *sta, int req, u32 src, u32 dst,
- u16 id, u16 seq)
-{
- if (req) {
- sta->icmp_echo_req_src = src;
- sta->icmp_echo_req_dst = dst;
- sta->icmp_echo_req_id = id;
- sta->icmp_echo_req_seq = seq;
- return;
- }
-
- if (sta->icmp_echo_req_src == dst &&
- sta->icmp_echo_req_dst == src &&
- sta->icmp_echo_req_id == id &&
- sta->icmp_echo_req_seq == seq) {
- sta->counters[WLANTEST_STA_COUNTER_PING_OK]++;
- if (sta->counters[WLANTEST_STA_COUNTER_ASSOCREQ_TX] == 0 &&
- sta->counters[WLANTEST_STA_COUNTER_REASSOCREQ_TX] == 0)
- sta->counters[
- WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC]++;
- wpa_printf(MSG_DEBUG, "ICMP echo (ping) match for STA " MACSTR,
- MAC2STR(sta->addr));
- }
-}
-
-
-static void rx_data_icmp(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr, u32 dst, u32 src,
- const u8 *data, size_t len, const u8 *peer_addr)
-{
- struct in_addr addr;
- char buf[20];
- const struct icmphdr *hdr;
- u16 id, seq;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
-
- hdr = (const struct icmphdr *) data;
- if (len < 4)
- return;
-
- /* TODO: check hdr->checksum */
-
- if (hdr->type != ICMP_ECHOREPLY && hdr->type != ICMP_ECHO)
- return;
- if (len < 8)
- return;
-
- id = ntohs(hdr->un.echo.id);
- seq = ntohs(hdr->un.echo.sequence);
-
- addr.s_addr = dst;
- snprintf(buf, sizeof(buf), "%s", inet_ntoa(addr));
- addr.s_addr = src;
- wpa_printf(MSG_DEBUG, "ICMP echo %s %s -> %s id=%04x seq=%u len=%u%s",
- hdr->type == ICMP_ECHO ? "request" : "response",
- inet_ntoa(addr), buf, id, seq, (unsigned) len - 8,
- peer_addr ? " [DL]" : "");
-
- bss = bss_find(wt, bssid);
- if (bss == NULL) {
- wpa_printf(MSG_INFO, "No BSS " MACSTR " known for ICMP packet",
- MAC2STR(bssid));
- return;
- }
-
- if (sta_addr == NULL)
- return; /* FromDS broadcast ping */
-
- sta = sta_find(bss, sta_addr);
- if (sta == NULL) {
- wpa_printf(MSG_INFO, "No STA " MACSTR " known for ICMP packet",
- MAC2STR(sta_addr));
- return;
- }
-
- ping_update(sta, hdr->type == ICMP_ECHO, src, dst, id, seq);
- if (peer_addr && (sta = sta_find(bss, peer_addr)))
- ping_update(sta, hdr->type == ICMP_ECHO, src, dst, id, seq);
-}
-
-
-void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
- const u8 *dst, const u8 *src, const u8 *data, size_t len,
- const u8 *peer_addr)
-{
- const struct iphdr *ip;
- const u8 *payload;
- size_t plen;
- u16 frag_off, tot_len;
-
- ip = (const struct iphdr *) data;
- if (len < sizeof(*ip))
- return;
- if (ip->version != 4) {
- wpa_printf(MSG_DEBUG, "Unexpected IP protocol version %u in "
- "IPv4 packet (bssid=" MACSTR " str=" MACSTR
- " dst=" MACSTR ")", ip->version, MAC2STR(bssid),
- MAC2STR(src), MAC2STR(dst));
- return;
- }
- if (ip->ihl * 4 < sizeof(*ip)) {
- wpa_printf(MSG_DEBUG, "Unexpected IP header length %u in "
- "IPv4 packet (bssid=" MACSTR " str=" MACSTR
- " dst=" MACSTR ")", ip->ihl, MAC2STR(bssid),
- MAC2STR(src), MAC2STR(dst));
- return;
- }
- if (ip->ihl * 4 > len) {
- wpa_printf(MSG_DEBUG, "Truncated IP header (ihl=%u len=%u) in "
- "IPv4 packet (bssid=" MACSTR " str=" MACSTR
- " dst=" MACSTR ")", ip->ihl, (unsigned) len,
- MAC2STR(bssid), MAC2STR(src), MAC2STR(dst));
- return;
- }
-
- /* TODO: check header checksum in ip->check */
-
- frag_off = be_to_host16(ip->frag_off);
- if (frag_off & 0x1fff) {
- wpa_printf(MSG_EXCESSIVE, "IP fragment reassembly not yet "
- "supported");
- return;
- }
-
- tot_len = be_to_host16(ip->tot_len);
- if (tot_len > len)
- return;
- if (tot_len < len)
- len = tot_len;
-
- payload = data + 4 * ip->ihl;
- plen = len - 4 * ip->ihl;
-
- switch (ip->protocol) {
- case IPPROTO_ICMP:
- rx_data_icmp(wt, bssid, sta_addr, ip->daddr, ip->saddr,
- payload, plen, peer_addr);
- break;
- }
-}
diff --git a/wlantest/rx_mgmt.c b/wlantest/rx_mgmt.c
deleted file mode 100644
index 0d72f22..0000000
--- a/wlantest/rx_mgmt.c
+++ /dev/null
@@ -1,1169 +0,0 @@
-/*
- * Received Management frame processing
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "crypto/aes_wrap.h"
-#include "wlantest.h"
-
-
-static const char * mgmt_stype(u16 stype)
-{
- switch (stype) {
- case WLAN_FC_STYPE_ASSOC_REQ:
- return "ASSOC-REQ";
- case WLAN_FC_STYPE_ASSOC_RESP:
- return "ASSOC-RESP";
- case WLAN_FC_STYPE_REASSOC_REQ:
- return "REASSOC-REQ";
- case WLAN_FC_STYPE_REASSOC_RESP:
- return "REASSOC-RESP";
- case WLAN_FC_STYPE_PROBE_REQ:
- return "PROBE-REQ";
- case WLAN_FC_STYPE_PROBE_RESP:
- return "PROBE-RESP";
- case WLAN_FC_STYPE_BEACON:
- return "BEACON";
- case WLAN_FC_STYPE_ATIM:
- return "ATIM";
- case WLAN_FC_STYPE_DISASSOC:
- return "DISASSOC";
- case WLAN_FC_STYPE_AUTH:
- return "AUTH";
- case WLAN_FC_STYPE_DEAUTH:
- return "DEAUTH";
- case WLAN_FC_STYPE_ACTION:
- return "ACTION";
- }
- return "??";
-}
-
-
-static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct ieee802_11_elems elems;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- if (bss->proberesp_seen)
- return; /* do not override with Beacon data */
- bss->capab_info = le_to_host16(mgmt->u.beacon.capab_info);
- if (ieee802_11_parse_elems(mgmt->u.beacon.variable,
- len - (mgmt->u.beacon.variable - data),
- &elems, 0) == ParseFailed) {
- if (bss->parse_error_reported)
- return;
- wpa_printf(MSG_INFO, "Invalid IEs in a Beacon frame from "
- MACSTR, MAC2STR(mgmt->sa));
- bss->parse_error_reported = 1;
- return;
- }
-
- bss_update(wt, bss, &elems);
-}
-
-
-static void rx_mgmt_probe_resp(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct ieee802_11_elems elems;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
-
- bss->capab_info = le_to_host16(mgmt->u.probe_resp.capab_info);
- if (ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
- len - (mgmt->u.probe_resp.variable - data),
- &elems, 0) == ParseFailed) {
- if (bss->parse_error_reported)
- return;
- wpa_printf(MSG_INFO, "Invalid IEs in a Probe Response frame "
- "from " MACSTR, MAC2STR(mgmt->sa));
- bss->parse_error_reported = 1;
- return;
- }
-
- bss_update(wt, bss, &elems);
-}
-
-
-static void rx_mgmt_auth(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- u16 alg, trans, status;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
- sta = sta_get(bss, mgmt->da);
- else
- sta = sta_get(bss, mgmt->sa);
- if (sta == NULL)
- return;
-
- if (len < 24 + 6) {
- wpa_printf(MSG_INFO, "Too short Authentication frame from "
- MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- alg = le_to_host16(mgmt->u.auth.auth_alg);
- trans = le_to_host16(mgmt->u.auth.auth_transaction);
- status = le_to_host16(mgmt->u.auth.status_code);
-
- wpa_printf(MSG_DEBUG, "AUTH " MACSTR " -> " MACSTR
- " (alg=%u trans=%u status=%u)",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da), alg, trans, status);
-
- if (alg == 0 && trans == 2 && status == 0) {
- if (sta->state == STATE1) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR
- " moved to State 2 with " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- sta->state = STATE2;
- }
- }
-
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
- sta->counters[WLANTEST_STA_COUNTER_AUTH_RX]++;
- else
- sta->counters[WLANTEST_STA_COUNTER_AUTH_TX]++;
-}
-
-
-static void deauth_all_stas(struct wlantest_bss *bss)
-{
- struct wlantest_sta *sta;
- dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
- if (sta->state == STATE1)
- continue;
- wpa_printf(MSG_DEBUG, "STA " MACSTR
- " moved to State 1 with " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- sta->state = STATE1;
- }
-}
-
-
-static void tdls_link_down(struct wlantest_bss *bss, struct wlantest_sta *sta)
-{
- struct wlantest_tdls *tdls;
- dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
- if ((tdls->init == sta || tdls->resp == sta) && tdls->link_up)
- {
- wpa_printf(MSG_DEBUG, "TDLS: Set link down based on "
- "STA deauth/disassoc");
- tdls->link_up = 0;
- }
- }
-}
-
-
-static void rx_mgmt_deauth(struct wlantest *wt, const u8 *data, size_t len,
- int valid)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- u16 fc, reason;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
- sta = sta_get(bss, mgmt->da);
- else
- sta = sta_get(bss, mgmt->sa);
-
- if (len < 24 + 2) {
- wpa_printf(MSG_INFO, "Too short Deauthentication frame from "
- MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- reason = le_to_host16(mgmt->u.deauth.reason_code);
- wpa_printf(MSG_DEBUG, "DEAUTH " MACSTR " -> " MACSTR
- " (reason=%u) (valid=%d)",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
- reason, valid);
- wpa_hexdump(MSG_MSGDUMP, "DEAUTH payload", data + 24, len - 24);
-
- if (sta == NULL) {
- if (valid && mgmt->da[0] == 0xff)
- deauth_all_stas(bss);
- return;
- }
-
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
- sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DEAUTH_RX :
- WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX]++;
- if (sta->pwrmgt && !sta->pspoll)
- sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_ASLEEP]++;
- else
- sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_AWAKE]++;
-
- fc = le_to_host16(mgmt->frame_control);
- if (!(fc & WLAN_FC_ISWEP) && reason == 6)
- sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_RC6]++;
- else if (!(fc & WLAN_FC_ISWEP) && reason == 7)
- sta->counters[WLANTEST_STA_COUNTER_DEAUTH_RX_RC7]++;
- } else
- sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DEAUTH_TX :
- WLANTEST_STA_COUNTER_INVALID_DEAUTH_TX]++;
-
- if (!valid) {
- wpa_printf(MSG_INFO, "Do not change STA " MACSTR " State "
- "since Disassociation frame was not protected "
- "correctly", MAC2STR(sta->addr));
- return;
- }
-
- if (sta->state != STATE1) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR
- " moved to State 1 with " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- sta->state = STATE1;
- }
- tdls_link_down(bss, sta);
-}
-
-
-static void rx_mgmt_assoc_req(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- struct ieee802_11_elems elems;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- sta = sta_get(bss, mgmt->sa);
- if (sta == NULL)
- return;
-
- if (len < 24 + 4) {
- wpa_printf(MSG_INFO, "Too short Association Request frame "
- "from " MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- wpa_printf(MSG_DEBUG, "ASSOCREQ " MACSTR " -> " MACSTR
- " (capab=0x%x listen_int=%u)",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
- le_to_host16(mgmt->u.assoc_req.capab_info),
- le_to_host16(mgmt->u.assoc_req.listen_interval));
-
- sta->counters[WLANTEST_STA_COUNTER_ASSOCREQ_TX]++;
-
- if (ieee802_11_parse_elems(mgmt->u.assoc_req.variable,
- len - (mgmt->u.assoc_req.variable - data),
- &elems, 0) == ParseFailed) {
- wpa_printf(MSG_INFO, "Invalid IEs in Association Request "
- "frame from " MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- sta->assocreq_capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
- sta->assocreq_listen_int =
- le_to_host16(mgmt->u.assoc_req.listen_interval);
- os_free(sta->assocreq_ies);
- sta->assocreq_ies_len = len - (mgmt->u.assoc_req.variable - data);
- sta->assocreq_ies = os_malloc(sta->assocreq_ies_len);
- if (sta->assocreq_ies)
- os_memcpy(sta->assocreq_ies, mgmt->u.assoc_req.variable,
- sta->assocreq_ies_len);
-
- sta_update_assoc(sta, &elems);
-}
-
-
-static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- u16 capab, status, aid;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- sta = sta_get(bss, mgmt->da);
- if (sta == NULL)
- return;
-
- if (len < 24 + 6) {
- wpa_printf(MSG_INFO, "Too short Association Response frame "
- "from " MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- capab = le_to_host16(mgmt->u.assoc_resp.capab_info);
- status = le_to_host16(mgmt->u.assoc_resp.status_code);
- aid = le_to_host16(mgmt->u.assoc_resp.aid);
-
- wpa_printf(MSG_DEBUG, "ASSOCRESP " MACSTR " -> " MACSTR
- " (capab=0x%x status=%u aid=%u)",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
- aid & 0x3fff);
-
- if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
- struct ieee802_11_elems elems;
- const u8 *ies = mgmt->u.assoc_resp.variable;
- size_t ies_len = len - (mgmt->u.assoc_resp.variable - data);
- if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
- ParseFailed) {
- wpa_printf(MSG_INFO, "Failed to parse IEs in "
- "AssocResp from " MACSTR,
- MAC2STR(mgmt->sa));
- } else if (elems.timeout_int == NULL ||
- elems.timeout_int_len != 5 ||
- elems.timeout_int[0] !=
- WLAN_TIMEOUT_ASSOC_COMEBACK) {
- wpa_printf(MSG_INFO, "No valid Timeout Interval IE "
- "with Assoc Comeback time in AssocResp "
- "(status=30) from " MACSTR,
- MAC2STR(mgmt->sa));
- } else {
- sta->counters[
- WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK]++;
- }
- }
-
- if (status)
- return;
-
- if ((aid & 0xc000) != 0xc000) {
- wpa_printf(MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
- "in Association Response from " MACSTR,
- MAC2STR(mgmt->sa));
- }
- sta->aid = aid & 0xc000;
-
- if (sta->state < STATE2) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR " was not in State 2 when "
- "getting associated", MAC2STR(sta->addr));
- }
-
- if (sta->state < STATE3) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR
- " moved to State 3 with " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- sta->state = STATE3;
- }
-}
-
-
-static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data,
- size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- struct ieee802_11_elems elems;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- sta = sta_get(bss, mgmt->sa);
- if (sta == NULL)
- return;
-
- if (len < 24 + 4 + ETH_ALEN) {
- wpa_printf(MSG_INFO, "Too short Reassociation Request frame "
- "from " MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- wpa_printf(MSG_DEBUG, "REASSOCREQ " MACSTR " -> " MACSTR
- " (capab=0x%x listen_int=%u current_ap=" MACSTR ")",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
- le_to_host16(mgmt->u.reassoc_req.capab_info),
- le_to_host16(mgmt->u.reassoc_req.listen_interval),
- MAC2STR(mgmt->u.reassoc_req.current_ap));
-
- sta->counters[WLANTEST_STA_COUNTER_REASSOCREQ_TX]++;
-
- if (ieee802_11_parse_elems(mgmt->u.reassoc_req.variable,
- len - (mgmt->u.reassoc_req.variable - data),
- &elems, 0) == ParseFailed) {
- wpa_printf(MSG_INFO, "Invalid IEs in Reassociation Request "
- "frame from " MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- sta->assocreq_capab_info =
- le_to_host16(mgmt->u.reassoc_req.capab_info);
- sta->assocreq_listen_int =
- le_to_host16(mgmt->u.reassoc_req.listen_interval);
- os_free(sta->assocreq_ies);
- sta->assocreq_ies_len = len - (mgmt->u.reassoc_req.variable - data);
- sta->assocreq_ies = os_malloc(sta->assocreq_ies_len);
- if (sta->assocreq_ies)
- os_memcpy(sta->assocreq_ies, mgmt->u.reassoc_req.variable,
- sta->assocreq_ies_len);
-
- sta_update_assoc(sta, &elems);
-}
-
-
-static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
- size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- u16 capab, status, aid;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- sta = sta_get(bss, mgmt->da);
- if (sta == NULL)
- return;
-
- if (len < 24 + 6) {
- wpa_printf(MSG_INFO, "Too short Reassociation Response frame "
- "from " MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- capab = le_to_host16(mgmt->u.reassoc_resp.capab_info);
- status = le_to_host16(mgmt->u.reassoc_resp.status_code);
- aid = le_to_host16(mgmt->u.reassoc_resp.aid);
-
- wpa_printf(MSG_DEBUG, "REASSOCRESP " MACSTR " -> " MACSTR
- " (capab=0x%x status=%u aid=%u)",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da), capab, status,
- aid & 0x3fff);
-
- if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
- struct ieee802_11_elems elems;
- const u8 *ies = mgmt->u.reassoc_resp.variable;
- size_t ies_len = len - (mgmt->u.reassoc_resp.variable - data);
- if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
- ParseFailed) {
- wpa_printf(MSG_INFO, "Failed to parse IEs in "
- "ReassocResp from " MACSTR,
- MAC2STR(mgmt->sa));
- } else if (elems.timeout_int == NULL ||
- elems.timeout_int_len != 5 ||
- elems.timeout_int[0] !=
- WLAN_TIMEOUT_ASSOC_COMEBACK) {
- wpa_printf(MSG_INFO, "No valid Timeout Interval IE "
- "with Assoc Comeback time in ReassocResp "
- "(status=30) from " MACSTR,
- MAC2STR(mgmt->sa));
- } else {
- sta->counters[
- WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK]++;
- }
- }
-
- if (status)
- return;
-
- if ((aid & 0xc000) != 0xc000) {
- wpa_printf(MSG_DEBUG, "Two MSBs of the AID were not set to 1 "
- "in Reassociation Response from " MACSTR,
- MAC2STR(mgmt->sa));
- }
- sta->aid = aid & 0xc000;
-
- if (sta->state < STATE2) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR " was not in State 2 when "
- "getting associated", MAC2STR(sta->addr));
- }
-
- if (sta->state < STATE3) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR
- " moved to State 3 with " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- sta->state = STATE3;
- }
-}
-
-
-static void disassoc_all_stas(struct wlantest_bss *bss)
-{
- struct wlantest_sta *sta;
- dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
- if (sta->state <= STATE2)
- continue;
- wpa_printf(MSG_DEBUG, "STA " MACSTR
- " moved to State 2 with " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- sta->state = STATE2;
- }
-}
-
-
-static void rx_mgmt_disassoc(struct wlantest *wt, const u8 *data, size_t len,
- int valid)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- u16 fc, reason;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
- sta = sta_get(bss, mgmt->da);
- else
- sta = sta_get(bss, mgmt->sa);
-
- if (len < 24 + 2) {
- wpa_printf(MSG_INFO, "Too short Disassociation frame from "
- MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- reason = le_to_host16(mgmt->u.disassoc.reason_code);
- wpa_printf(MSG_DEBUG, "DISASSOC " MACSTR " -> " MACSTR
- " (reason=%u) (valid=%d)",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
- reason, valid);
- wpa_hexdump(MSG_MSGDUMP, "DISASSOC payload", data + 24, len - 24);
-
- if (sta == NULL) {
- if (valid && mgmt->da[0] == 0xff)
- disassoc_all_stas(bss);
- return;
- }
-
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
- sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DISASSOC_RX :
- WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX]++;
- if (sta->pwrmgt && !sta->pspoll)
- sta->counters[
- WLANTEST_STA_COUNTER_DISASSOC_RX_ASLEEP]++;
- else
- sta->counters[
- WLANTEST_STA_COUNTER_DISASSOC_RX_AWAKE]++;
-
- fc = le_to_host16(mgmt->frame_control);
- if (!(fc & WLAN_FC_ISWEP) && reason == 6)
- sta->counters[WLANTEST_STA_COUNTER_DISASSOC_RX_RC6]++;
- else if (!(fc & WLAN_FC_ISWEP) && reason == 7)
- sta->counters[WLANTEST_STA_COUNTER_DISASSOC_RX_RC7]++;
- } else
- sta->counters[valid ? WLANTEST_STA_COUNTER_VALID_DISASSOC_TX :
- WLANTEST_STA_COUNTER_INVALID_DISASSOC_TX]++;
-
- if (!valid) {
- wpa_printf(MSG_INFO, "Do not change STA " MACSTR " State "
- "since Disassociation frame was not protected "
- "correctly", MAC2STR(sta->addr));
- return;
- }
-
- if (sta->state < STATE2) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR " was not in State 2 or 3 "
- "when getting disassociated", MAC2STR(sta->addr));
- }
-
- if (sta->state > STATE2) {
- wpa_printf(MSG_DEBUG, "STA " MACSTR
- " moved to State 2 with " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- sta->state = STATE2;
- }
- tdls_link_down(bss, sta);
-}
-
-
-static void rx_mgmt_action_sa_query_req(struct wlantest *wt,
- struct wlantest_sta *sta,
- const struct ieee80211_mgmt *mgmt,
- size_t len, int valid)
-{
- const u8 *rx_id;
- u8 *id;
-
- rx_id = (const u8 *) mgmt->u.action.u.sa_query_req.trans_id;
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
- id = sta->ap_sa_query_tr;
- else
- id = sta->sta_sa_query_tr;
- wpa_printf(MSG_INFO, "SA Query Request " MACSTR " -> " MACSTR
- " (trans_id=%02x%02x)%s",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da), rx_id[0], rx_id[1],
- valid ? "" : " (invalid protection)");
- os_memcpy(id, mgmt->u.action.u.sa_query_req.trans_id, 2);
- if (os_memcmp(mgmt->sa, sta->addr, ETH_ALEN) == 0)
- sta->counters[valid ?
- WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_TX :
- WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_TX]++;
- else
- sta->counters[valid ?
- WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_RX :
- WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_RX]++;
-}
-
-
-static void rx_mgmt_action_sa_query_resp(struct wlantest *wt,
- struct wlantest_sta *sta,
- const struct ieee80211_mgmt *mgmt,
- size_t len, int valid)
-{
- const u8 *rx_id;
- u8 *id;
- int match;
-
- rx_id = (const u8 *) mgmt->u.action.u.sa_query_resp.trans_id;
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
- id = sta->sta_sa_query_tr;
- else
- id = sta->ap_sa_query_tr;
- match = os_memcmp(rx_id, id, 2) == 0;
- wpa_printf(MSG_INFO, "SA Query Response " MACSTR " -> " MACSTR
- " (trans_id=%02x%02x; %s)%s",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da), rx_id[0], rx_id[1],
- match ? "match" : "mismatch",
- valid ? "" : " (invalid protection)");
- if (os_memcmp(mgmt->sa, sta->addr, ETH_ALEN) == 0)
- sta->counters[(valid && match) ?
- WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_TX :
- WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_TX]++;
- else
- sta->counters[(valid && match) ?
- WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_RX :
- WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX]++;
-}
-
-
-static void rx_mgmt_action_sa_query(struct wlantest *wt,
- struct wlantest_sta *sta,
- const struct ieee80211_mgmt *mgmt,
- size_t len, int valid)
-{
- if (len < 24 + 2 + WLAN_SA_QUERY_TR_ID_LEN) {
- wpa_printf(MSG_INFO, "Too short SA Query frame from " MACSTR,
- MAC2STR(mgmt->sa));
- return;
- }
-
- if (len > 24 + 2 + WLAN_SA_QUERY_TR_ID_LEN) {
- size_t elen = len - (24 + 2 + WLAN_SA_QUERY_TR_ID_LEN);
- wpa_printf(MSG_INFO, "Unexpected %u octets of extra data at "
- "the end of SA Query frame from " MACSTR,
- (unsigned) elen, MAC2STR(mgmt->sa));
- wpa_hexdump(MSG_INFO, "SA Query extra data",
- ((const u8 *) mgmt) + len - elen, elen);
- }
-
- switch (mgmt->u.action.u.sa_query_req.action) {
- case WLAN_SA_QUERY_REQUEST:
- rx_mgmt_action_sa_query_req(wt, sta, mgmt, len, valid);
- break;
- case WLAN_SA_QUERY_RESPONSE:
- rx_mgmt_action_sa_query_resp(wt, sta, mgmt, len, valid);
- break;
- default:
- wpa_printf(MSG_INFO, "Unexpected SA Query action value %u "
- "from " MACSTR,
- mgmt->u.action.u.sa_query_req.action,
- MAC2STR(mgmt->sa));
- }
-}
-
-
-static void rx_mgmt_action(struct wlantest *wt, const u8 *data, size_t len,
- int valid)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- if (mgmt->da[0] & 0x01) {
- wpa_printf(MSG_DEBUG, "Group addressed Action frame: DA="
- MACSTR " SA=" MACSTR " BSSID=" MACSTR
- " category=%u",
- MAC2STR(mgmt->da), MAC2STR(mgmt->sa),
- MAC2STR(mgmt->bssid), mgmt->u.action.category);
- return; /* Ignore group addressed Action frames for now */
- }
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
- sta = sta_get(bss, mgmt->da);
- else
- sta = sta_get(bss, mgmt->sa);
- if (sta == NULL)
- return;
-
- if (len < 24 + 1) {
- wpa_printf(MSG_INFO, "Too short Action frame from "
- MACSTR, MAC2STR(mgmt->sa));
- return;
- }
-
- wpa_printf(MSG_DEBUG, "ACTION " MACSTR " -> " MACSTR
- " (category=%u) (valid=%d)",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da),
- mgmt->u.action.category, valid);
- wpa_hexdump(MSG_MSGDUMP, "ACTION payload", data + 24, len - 24);
-
- if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
- sta->state < STATE3) {
- wpa_printf(MSG_INFO, "Action frame sent when STA is not in "
- "State 3 (SA=" MACSTR " DATA=" MACSTR ")",
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
- }
-
- switch (mgmt->u.action.category) {
- case WLAN_ACTION_SA_QUERY:
- rx_mgmt_action_sa_query(wt, sta, mgmt, len, valid);
- break;
- }
-}
-
-
-static int check_mmie_mic(const u8 *igtk, const u8 *data, size_t len)
-{
- u8 *buf;
- u8 mic[16];
- u16 fc;
- const struct ieee80211_hdr *hdr;
-
- buf = os_malloc(len + 20 - 24);
- if (buf == NULL)
- return -1;
-
- /* BIP AAD: FC(masked) A1 A2 A3 */
- hdr = (const struct ieee80211_hdr *) data;
- fc = le_to_host16(hdr->frame_control);
- fc &= ~(WLAN_FC_RETRY | WLAN_FC_PWRMGT | WLAN_FC_MOREDATA);
- WPA_PUT_LE16(buf, fc);
- os_memcpy(buf + 2, hdr->addr1, 3 * ETH_ALEN);
-
- /* Frame body with MMIE MIC masked to zero */
- os_memcpy(buf + 20, data + 24, len - 24 - 8);
- os_memset(buf + 20 + len - 24 - 8, 0, 8);
-
- wpa_hexdump(MSG_MSGDUMP, "BIP: AAD|Body(masked)", buf, len + 20 - 24);
- /* MIC = L(AES-128-CMAC(AAD || Frame Body(masked)), 0, 64) */
- if (omac1_aes_128(igtk, buf, len + 20 - 24, mic) < 0) {
- os_free(buf);
- return -1;
- }
-
- os_free(buf);
-
- if (os_memcmp(data + len - 8, mic, 8) != 0)
- return -1;
-
- return 0;
-}
-
-
-static int check_bip(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- u16 fc, stype;
- const u8 *mmie;
- u16 keyid;
- struct wlantest_bss *bss;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- fc = le_to_host16(mgmt->frame_control);
- stype = WLAN_FC_GET_STYPE(fc);
-
- if (stype == WLAN_FC_STYPE_ACTION) {
- if (len < 24 + 1)
- return 0;
- if (mgmt->u.action.category == WLAN_ACTION_PUBLIC)
- return 0; /* Not a robust management frame */
- }
-
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return 0; /* No key known yet */
-
- if (len < 24 + 18 || data[len - 18] != WLAN_EID_MMIE ||
- data[len - 17] != 16) {
- /* No MMIE */
- if (bss->rsn_capab & WPA_CAPABILITY_MFPC) {
- wpa_printf(MSG_INFO, "Robust group-addressed "
- "management frame sent without BIP by "
- MACSTR, MAC2STR(mgmt->sa));
- bss->counters[WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE]++;
- return -1;
- }
- return 0;
- }
-
- mmie = data + len - 16;
- keyid = WPA_GET_LE16(mmie);
- if (keyid & 0xf000) {
- wpa_printf(MSG_INFO, "MMIE KeyID reserved bits not zero "
- "(%04x) from " MACSTR, keyid, MAC2STR(mgmt->sa));
- keyid &= 0x0fff;
- }
- if (keyid < 4 || keyid > 5) {
- wpa_printf(MSG_INFO, "Unexpected MMIE KeyID %u from " MACSTR,
- keyid, MAC2STR(mgmt->sa));
- bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
- return 0;
- }
- wpa_printf(MSG_DEBUG, "MMIE KeyID %u", keyid);
- wpa_hexdump(MSG_MSGDUMP, "MMIE IPN", mmie + 2, 6);
- wpa_hexdump(MSG_MSGDUMP, "MMIE MIC", mmie + 8, 8);
-
- if (!bss->igtk_set[keyid]) {
- wpa_printf(MSG_DEBUG, "No IGTK known to validate BIP frame");
- return 0;
- }
-
- if (os_memcmp(mmie + 2, bss->ipn[keyid], 6) <= 0) {
- wpa_printf(MSG_INFO, "BIP replay detected: SA=" MACSTR,
- MAC2STR(mgmt->sa));
- wpa_hexdump(MSG_INFO, "RX IPN", mmie + 2, 6);
- wpa_hexdump(MSG_INFO, "Last RX IPN", bss->ipn[keyid], 6);
- }
-
- if (check_mmie_mic(bss->igtk[keyid], data, len) < 0) {
- wpa_printf(MSG_INFO, "Invalid MMIE MIC in a frame from "
- MACSTR, MAC2STR(mgmt->sa));
- bss->counters[WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE]++;
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "Valid MMIE MIC");
- os_memcpy(bss->ipn[keyid], mmie + 2, 6);
- bss->counters[WLANTEST_BSS_COUNTER_VALID_BIP_MMIE]++;
-
- if (stype == WLAN_FC_STYPE_DEAUTH)
- bss->counters[WLANTEST_BSS_COUNTER_BIP_DEAUTH]++;
- else if (stype == WLAN_FC_STYPE_DISASSOC)
- bss->counters[WLANTEST_BSS_COUNTER_BIP_DISASSOC]++;
-
- return 0;
-}
-
-
-static u8 * mgmt_ccmp_decrypt(struct wlantest *wt, const u8 *data, size_t len,
- size_t *dlen)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
- const struct ieee80211_hdr *hdr;
- int keyid;
- u8 *decrypted, *frame = NULL;
- u8 pn[6], *rsc;
-
- hdr = (const struct ieee80211_hdr *) data;
- bss = bss_get(wt, hdr->addr3);
- if (bss == NULL)
- return NULL;
- if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
- sta = sta_get(bss, hdr->addr2);
- else
- sta = sta_get(bss, hdr->addr1);
- if (sta == NULL || !sta->ptk_set) {
- wpa_printf(MSG_MSGDUMP, "No PTK known to decrypt the frame");
- return NULL;
- }
-
- if (len < 24 + 4)
- return NULL;
-
- if (!(data[24 + 3] & 0x20)) {
- wpa_printf(MSG_INFO, "Expected CCMP frame from " MACSTR
- " did not have ExtIV bit set to 1",
- MAC2STR(hdr->addr2));
- return NULL;
- }
-
- if (data[24 + 2] != 0 || (data[24 + 3] & 0x1f) != 0) {
- wpa_printf(MSG_INFO, "CCMP mgmt frame from " MACSTR " used "
- "non-zero reserved bit", MAC2STR(hdr->addr2));
- }
-
- keyid = data[24 + 3] >> 6;
- if (keyid != 0) {
- wpa_printf(MSG_INFO, "Unexpected non-zero KeyID %d in "
- "individually addressed Management frame from "
- MACSTR, keyid, MAC2STR(hdr->addr2));
- }
-
- if (os_memcmp(hdr->addr1, hdr->addr3, ETH_ALEN) == 0)
- rsc = sta->rsc_tods[16];
- else
- rsc = sta->rsc_fromds[16];
-
- ccmp_get_pn(pn, data + 24);
- if (os_memcmp(pn, rsc, 6) <= 0) {
- u16 seq_ctrl = le_to_host16(hdr->seq_ctrl);
- wpa_printf(MSG_INFO, "CCMP/TKIP replay detected: A1=" MACSTR
- " A2=" MACSTR " A3=" MACSTR " seq=%u frag=%u",
- MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3),
- WLAN_GET_SEQ_SEQ(seq_ctrl),
- WLAN_GET_SEQ_FRAG(seq_ctrl));
- wpa_hexdump(MSG_INFO, "RX PN", pn, 6);
- wpa_hexdump(MSG_INFO, "RSC", rsc, 6);
- }
-
- decrypted = ccmp_decrypt(sta->ptk.tk1, hdr, data + 24, len - 24, dlen);
- if (decrypted) {
- os_memcpy(rsc, pn, 6);
- frame = os_malloc(24 + *dlen);
- if (frame) {
- os_memcpy(frame, data, 24);
- os_memcpy(frame + 24, decrypted, *dlen);
- *dlen += 24;
- }
- }
-
- os_free(decrypted);
-
- return frame;
-}
-
-
-static int check_mgmt_ccmp(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_mgmt *mgmt;
- u16 fc;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
-
- mgmt = (const struct ieee80211_mgmt *) data;
- fc = le_to_host16(mgmt->frame_control);
-
- if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION) {
- if (len > 24 &&
- mgmt->u.action.category == WLAN_ACTION_PUBLIC)
- return 0; /* Not a robust management frame */
- }
-
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return 0;
- if (os_memcmp(mgmt->da, mgmt->bssid, ETH_ALEN) == 0)
- sta = sta_get(bss, mgmt->sa);
- else
- sta = sta_get(bss, mgmt->da);
- if (sta == NULL)
- return 0;
-
- if ((sta->rsn_capab & WPA_CAPABILITY_MFPC) &&
- (sta->state == STATE3 ||
- WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_ACTION)) {
- wpa_printf(MSG_INFO, "Robust individually-addressed "
- "management frame sent without CCMP by "
- MACSTR, MAC2STR(mgmt->sa));
- return -1;
- }
-
- return 0;
-}
-
-
-void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ieee80211_hdr *hdr;
- u16 fc, stype;
- int valid = 1;
- u8 *decrypted = NULL;
- size_t dlen;
-
- if (len < 24)
- return;
-
- hdr = (const struct ieee80211_hdr *) data;
- fc = le_to_host16(hdr->frame_control);
- wt->rx_mgmt++;
- stype = WLAN_FC_GET_STYPE(fc);
-
- if ((hdr->addr1[0] & 0x01) &&
- (stype == WLAN_FC_STYPE_DEAUTH ||
- stype == WLAN_FC_STYPE_DISASSOC ||
- stype == WLAN_FC_STYPE_ACTION)) {
- if (check_bip(wt, data, len) < 0)
- valid = 0;
- }
-
- wpa_printf((stype == WLAN_FC_STYPE_BEACON ||
- stype == WLAN_FC_STYPE_PROBE_RESP ||
- stype == WLAN_FC_STYPE_PROBE_REQ) ?
- MSG_EXCESSIVE : MSG_MSGDUMP,
- "MGMT %s%s%s DA=" MACSTR " SA=" MACSTR " BSSID=" MACSTR,
- mgmt_stype(stype),
- fc & WLAN_FC_PWRMGT ? " PwrMgt" : "",
- fc & WLAN_FC_ISWEP ? " Prot" : "",
- MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3));
-
- if ((fc & WLAN_FC_ISWEP) &&
- !(hdr->addr1[0] & 0x01) &&
- (stype == WLAN_FC_STYPE_DEAUTH ||
- stype == WLAN_FC_STYPE_DISASSOC ||
- stype == WLAN_FC_STYPE_ACTION)) {
- decrypted = mgmt_ccmp_decrypt(wt, data, len, &dlen);
- if (decrypted) {
- write_pcap_decrypted(wt, decrypted, dlen, NULL, 0);
- data = decrypted;
- len = dlen;
- } else
- valid = 0;
- }
-
- if (!(fc & WLAN_FC_ISWEP) &&
- !(hdr->addr1[0] & 0x01) &&
- (stype == WLAN_FC_STYPE_DEAUTH ||
- stype == WLAN_FC_STYPE_DISASSOC ||
- stype == WLAN_FC_STYPE_ACTION)) {
- if (check_mgmt_ccmp(wt, data, len) < 0)
- valid = 0;
- }
-
- switch (stype) {
- case WLAN_FC_STYPE_BEACON:
- rx_mgmt_beacon(wt, data, len);
- break;
- case WLAN_FC_STYPE_PROBE_RESP:
- rx_mgmt_probe_resp(wt, data, len);
- break;
- case WLAN_FC_STYPE_AUTH:
- rx_mgmt_auth(wt, data, len);
- break;
- case WLAN_FC_STYPE_DEAUTH:
- rx_mgmt_deauth(wt, data, len, valid);
- break;
- case WLAN_FC_STYPE_ASSOC_REQ:
- rx_mgmt_assoc_req(wt, data, len);
- break;
- case WLAN_FC_STYPE_ASSOC_RESP:
- rx_mgmt_assoc_resp(wt, data, len);
- break;
- case WLAN_FC_STYPE_REASSOC_REQ:
- rx_mgmt_reassoc_req(wt, data, len);
- break;
- case WLAN_FC_STYPE_REASSOC_RESP:
- rx_mgmt_reassoc_resp(wt, data, len);
- break;
- case WLAN_FC_STYPE_DISASSOC:
- rx_mgmt_disassoc(wt, data, len, valid);
- break;
- case WLAN_FC_STYPE_ACTION:
- rx_mgmt_action(wt, data, len, valid);
- break;
- }
-
- os_free(decrypted);
-
- wt->last_mgmt_valid = valid;
-}
-
-
-static void rx_mgmt_deauth_ack(struct wlantest *wt,
- const struct ieee80211_hdr *hdr)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
-
- mgmt = (const struct ieee80211_mgmt *) hdr;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
- sta = sta_get(bss, mgmt->da);
- else
- sta = sta_get(bss, mgmt->sa);
- if (sta == NULL)
- return;
-
- wpa_printf(MSG_DEBUG, "DEAUTH from " MACSTR " acknowledged by " MACSTR,
- MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
- int c;
- c = wt->last_mgmt_valid ?
- WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK :
- WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK;
- sta->counters[c]++;
- }
-}
-
-
-static void rx_mgmt_disassoc_ack(struct wlantest *wt,
- const struct ieee80211_hdr *hdr)
-{
- const struct ieee80211_mgmt *mgmt;
- struct wlantest_bss *bss;
- struct wlantest_sta *sta;
-
- mgmt = (const struct ieee80211_mgmt *) hdr;
- bss = bss_get(wt, mgmt->bssid);
- if (bss == NULL)
- return;
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0)
- sta = sta_get(bss, mgmt->da);
- else
- sta = sta_get(bss, mgmt->sa);
- if (sta == NULL)
- return;
-
- wpa_printf(MSG_DEBUG, "DISASSOC from " MACSTR " acknowledged by "
- MACSTR, MAC2STR(mgmt->sa), MAC2STR(mgmt->da));
- if (os_memcmp(mgmt->sa, mgmt->bssid, ETH_ALEN) == 0) {
- int c;
- c = wt->last_mgmt_valid ?
- WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK :
- WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK;
- sta->counters[c]++;
- }
-}
-
-
-void rx_mgmt_ack(struct wlantest *wt, const struct ieee80211_hdr *hdr)
-{
- u16 fc, stype;
- fc = le_to_host16(hdr->frame_control);
- stype = WLAN_FC_GET_STYPE(fc);
-
- wpa_printf(MSG_MSGDUMP, "MGMT ACK: stype=%u a1=" MACSTR " a2=" MACSTR
- " a3=" MACSTR,
- stype, MAC2STR(hdr->addr1), MAC2STR(hdr->addr2),
- MAC2STR(hdr->addr3));
-
- switch (stype) {
- case WLAN_FC_STYPE_DEAUTH:
- rx_mgmt_deauth_ack(wt, hdr);
- break;
- case WLAN_FC_STYPE_DISASSOC:
- rx_mgmt_disassoc_ack(wt, hdr);
- break;
- }
-}
diff --git a/wlantest/rx_tdls.c b/wlantest/rx_tdls.c
deleted file mode 100644
index 08a29a5..0000000
--- a/wlantest/rx_tdls.c
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- * Received Data frame processing for TDLS packets
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "crypto/sha256.h"
-#include "crypto/crypto.h"
-#include "crypto/aes_wrap.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "wlantest.h"
-
-
-static struct wlantest_tdls * get_tdls(struct wlantest *wt, const u8 *linkid,
- int create_new, const u8 *bssid)
-{
- struct wlantest_bss *bss;
- struct wlantest_sta *init, *resp;
- struct wlantest_tdls *tdls;
-
- bss = bss_find(wt, linkid);
- if (bss == NULL && bssid) {
- bss = bss_find(wt, bssid);
- if (bss)
- wpa_printf(MSG_INFO, "TDLS: Incorrect BSSID " MACSTR
- " in LinkId?! (init=" MACSTR " resp="
- MACSTR ")",
- MAC2STR(linkid), MAC2STR(linkid + ETH_ALEN),
- MAC2STR(linkid + 2 * ETH_ALEN));
- }
- if (bss == NULL)
- return NULL;
-
- init = sta_find(bss, linkid + ETH_ALEN);
- if (init == NULL)
- return NULL;
-
- resp = sta_find(bss, linkid + 2 * ETH_ALEN);
- if (resp == NULL)
- return NULL;
-
- dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
- if (tdls->init == init && tdls->resp == resp)
- return tdls;
- }
-
- if (!create_new)
- return NULL;
-
- tdls = os_zalloc(sizeof(*tdls));
- if (tdls == NULL)
- return NULL;
- tdls->init = init;
- tdls->resp = resp;
- dl_list_add(&bss->tdls, &tdls->list);
- return tdls;
-}
-
-
-static int tdls_derive_tpk(struct wlantest_tdls *tdls, const u8 *bssid,
- const u8 *ftie, u8 ftie_len)
-{
- const struct rsn_ftie *f;
- u8 key_input[SHA256_MAC_LEN];
- const u8 *nonce[2];
- size_t len[2];
- u8 data[3 * ETH_ALEN];
-
- if (ftie == NULL || ftie_len < sizeof(struct rsn_ftie))
- return 0;
-
- f = (const struct rsn_ftie *) ftie;
- wpa_hexdump(MSG_DEBUG, "TDLS ANonce", f->anonce, WPA_NONCE_LEN);
- wpa_hexdump(MSG_DEBUG, "TDLS SNonce", f->snonce, WPA_NONCE_LEN);
-
- /*
- * IEEE Std 802.11z-2010 8.5.9.1:
- * TPK-Key-Input = SHA-256(min(SNonce, ANonce) || max(SNonce, ANonce))
- */
- len[0] = WPA_NONCE_LEN;
- len[1] = WPA_NONCE_LEN;
- if (os_memcmp(f->anonce, f->snonce, WPA_NONCE_LEN) < 0) {
- nonce[0] = f->anonce;
- nonce[1] = f->snonce;
- } else {
- nonce[0] = f->snonce;
- nonce[1] = f->anonce;
- }
- sha256_vector(2, nonce, len, key_input);
- wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-Key-Input",
- key_input, SHA256_MAC_LEN);
-
- /*
- * TPK-Key-Data = KDF-N_KEY(TPK-Key-Input, "TDLS PMK",
- * min(MAC_I, MAC_R) || max(MAC_I, MAC_R) || BSSID || N_KEY)
- * TODO: is N_KEY really included in KDF Context and if so, in which
- * presentation format (little endian 16-bit?) is it used? It gets
- * added by the KDF anyway..
- */
-
- if (os_memcmp(tdls->init->addr, tdls->resp->addr, ETH_ALEN) < 0) {
- os_memcpy(data, tdls->init->addr, ETH_ALEN);
- os_memcpy(data + ETH_ALEN, tdls->resp->addr, ETH_ALEN);
- } else {
- os_memcpy(data, tdls->resp->addr, ETH_ALEN);
- os_memcpy(data + ETH_ALEN, tdls->init->addr, ETH_ALEN);
- }
- os_memcpy(data + 2 * ETH_ALEN, bssid, ETH_ALEN);
- wpa_hexdump(MSG_DEBUG, "TDLS: KDF Context", data, sizeof(data));
-
- sha256_prf(key_input, SHA256_MAC_LEN, "TDLS PMK", data, sizeof(data),
- (u8 *) &tdls->tpk, sizeof(tdls->tpk));
- wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-KCK",
- tdls->tpk.kck, sizeof(tdls->tpk.kck));
- wpa_hexdump_key(MSG_DEBUG, "TDLS: TPK-TK",
- tdls->tpk.tk, sizeof(tdls->tpk.tk));
-
- return 1;
-}
-
-
-static int tdls_verify_mic(struct wlantest_tdls *tdls, u8 trans_seq,
- struct ieee802_11_elems *elems)
-{
- u8 *buf, *pos;
- int len;
- u8 mic[16];
- int ret;
- const struct rsn_ftie *rx_ftie;
- struct rsn_ftie *tmp_ftie;
-
- if (elems->link_id == NULL || elems->rsn_ie == NULL ||
- elems->timeout_int == NULL || elems->ftie == NULL)
- return -1;
-
- len = 2 * ETH_ALEN + 1 + 2 + 18 + 2 + elems->rsn_ie_len +
- 2 + elems->timeout_int_len + 2 + elems->ftie_len;
-
- buf = os_zalloc(len);
- if (buf == NULL)
- return -1;
-
- pos = buf;
- /* 1) TDLS initiator STA MAC address */
- os_memcpy(pos, elems->link_id + ETH_ALEN, ETH_ALEN);
- pos += ETH_ALEN;
- /* 2) TDLS responder STA MAC address */
- os_memcpy(pos, elems->link_id + 2 * ETH_ALEN, ETH_ALEN);
- pos += ETH_ALEN;
- /* 3) Transaction Sequence number */
- *pos++ = trans_seq;
- /* 4) Link Identifier IE */
- os_memcpy(pos, elems->link_id - 2, 2 + 18);
- pos += 2 + 18;
- /* 5) RSN IE */
- os_memcpy(pos, elems->rsn_ie - 2, 2 + elems->rsn_ie_len);
- pos += 2 + elems->rsn_ie_len;
- /* 6) Timeout Interval IE */
- os_memcpy(pos, elems->timeout_int - 2, 2 + elems->timeout_int_len);
- pos += 2 + elems->timeout_int_len;
- /* 7) FTIE, with the MIC field of the FTIE set to 0 */
- os_memcpy(pos, elems->ftie - 2, 2 + elems->ftie_len);
- pos += 2;
- tmp_ftie = (struct rsn_ftie *) pos;
- os_memset(tmp_ftie->mic, 0, 16);
- pos += elems->ftie_len;
-
- wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
- wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", tdls->tpk.kck, 16);
- ret = omac1_aes_128(tdls->tpk.kck, buf, pos - buf, mic);
- os_free(buf);
- if (ret)
- return -1;
- wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
- rx_ftie = (const struct rsn_ftie *) elems->ftie;
-
- if (os_memcmp(mic, rx_ftie->mic, 16) == 0) {
- wpa_printf(MSG_DEBUG, "TDLS: Valid MIC");
- return 0;
- }
- wpa_printf(MSG_DEBUG, "TDLS: Invalid MIC");
- return -1;
-}
-
-
-static void rx_data_tdls_setup_request(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr, const u8 *dst,
- const u8 *src,
- const u8 *data, size_t len)
-{
- struct ieee802_11_elems elems;
- struct wlantest_tdls *tdls;
-
- if (len < 3) {
- wpa_printf(MSG_INFO, "Too short TDLS Setup Request " MACSTR
- " -> " MACSTR, MAC2STR(src), MAC2STR(dst));
- return;
- }
- wpa_printf(MSG_DEBUG, "TDLS Setup Request " MACSTR " -> "
- MACSTR, MAC2STR(src), MAC2STR(dst));
-
- if (ieee802_11_parse_elems(data + 3, len - 3, &elems, 1) ==
- ParseFailed || elems.link_id == NULL)
- return;
- wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
- " initiator STA " MACSTR " responder STA " MACSTR,
- MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
- MAC2STR(elems.link_id + 2 * ETH_ALEN));
- tdls = get_tdls(wt, elems.link_id, 1, bssid);
- if (tdls) {
- tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_REQ]++;
- tdls->dialog_token = data[0];
- }
-}
-
-
-static void rx_data_tdls_setup_response_failure(struct wlantest *wt,
- const u8 *bssid,
- const u8 *sta_addr,
- u8 dialog_token, u16 status)
-{
- struct wlantest_bss *bss;
- struct wlantest_tdls *tdls;
- struct wlantest_sta *sta;
-
- if (status == WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_INFO, "TDLS: Invalid TDLS Setup Response from "
- MACSTR, MAC2STR(sta_addr));
- return;
- }
-
- bss = bss_find(wt, bssid);
- if (!bss)
- return;
- sta = sta_find(bss, sta_addr);
- if (!sta)
- return;
-
- dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
- if (tdls->resp == sta) {
- if (dialog_token != tdls->dialog_token) {
- wpa_printf(MSG_DEBUG, "TDLS: Dialog token "
- "mismatch in TDLS Setup Response "
- "(failure)");
- break;
- }
- wpa_printf(MSG_DEBUG, "TDLS: Found matching TDLS "
- "setup session based on dialog token");
- tdls->counters[
- WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL]++;
- break;
- }
- }
-}
-
-
-static void rx_data_tdls_setup_response(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr, const u8 *dst,
- const u8 *src,
- const u8 *data, size_t len)
-{
- u16 status;
- struct ieee802_11_elems elems;
- struct wlantest_tdls *tdls;
-
- if (len < 3) {
- wpa_printf(MSG_INFO, "Too short TDLS Setup Response " MACSTR
- " -> " MACSTR, MAC2STR(src), MAC2STR(dst));
- return;
- }
- status = WPA_GET_LE16(data);
- wpa_printf(MSG_DEBUG, "TDLS Setup Response " MACSTR " -> "
- MACSTR " (status %d)",
- MAC2STR(src), MAC2STR(dst), status);
- if (len < 5 && status == 0) {
- wpa_printf(MSG_INFO, "Too short TDLS Setup Response " MACSTR
- " -> " MACSTR, MAC2STR(src), MAC2STR(dst));
- return;
- }
-
- if (len < 5 ||
- ieee802_11_parse_elems(data + 5, len - 5, &elems, 1) ==
- ParseFailed || elems.link_id == NULL) {
- /* Need to match TDLS link based on Dialog Token */
- rx_data_tdls_setup_response_failure(wt, bssid, sta_addr,
- data[2], status);
- return;
- }
- wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
- " initiator STA " MACSTR " responder STA " MACSTR,
- MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
- MAC2STR(elems.link_id + 2 * ETH_ALEN));
-
- tdls = get_tdls(wt, elems.link_id, 1, bssid);
- if (!tdls)
- return;
- if (status)
- tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL]++;
- else
- tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_RESP_OK]++;
-
- if (status != WLAN_STATUS_SUCCESS)
- return;
-
- if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1)
- return;
- if (tdls_verify_mic(tdls, 2, &elems) == 0) {
- tdls->dialog_token = data[2];
- wpa_printf(MSG_DEBUG, "TDLS: Dialog Token for the link: %u",
- tdls->dialog_token);
- }
-}
-
-
-static void rx_data_tdls_setup_confirm_failure(struct wlantest *wt,
- const u8 *bssid,
- const u8 *src,
- u8 dialog_token, u16 status)
-{
- struct wlantest_bss *bss;
- struct wlantest_tdls *tdls;
- struct wlantest_sta *sta;
-
- if (status == WLAN_STATUS_SUCCESS) {
- wpa_printf(MSG_INFO, "TDLS: Invalid TDLS Setup Confirm from "
- MACSTR, MAC2STR(src));
- return;
- }
-
- bss = bss_find(wt, bssid);
- if (!bss)
- return;
- sta = sta_find(bss, src);
- if (!sta)
- return;
-
- dl_list_for_each(tdls, &bss->tdls, struct wlantest_tdls, list) {
- if (tdls->init == sta) {
- if (dialog_token != tdls->dialog_token) {
- wpa_printf(MSG_DEBUG, "TDLS: Dialog token "
- "mismatch in TDLS Setup Confirm "
- "(failure)");
- break;
- }
- wpa_printf(MSG_DEBUG, "TDLS: Found matching TDLS "
- "setup session based on dialog token");
- tdls->counters[
- WLANTEST_TDLS_COUNTER_SETUP_CONF_FAIL]++;
- break;
- }
- }
-}
-
-
-static void rx_data_tdls_setup_confirm(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr, const u8 *dst,
- const u8 *src,
- const u8 *data, size_t len)
-{
- u16 status;
- struct ieee802_11_elems elems;
- struct wlantest_tdls *tdls;
- u8 link_id[3 * ETH_ALEN];
-
- if (len < 3) {
- wpa_printf(MSG_INFO, "Too short TDLS Setup Confirm " MACSTR
- " -> " MACSTR, MAC2STR(src), MAC2STR(dst));
- return;
- }
- status = WPA_GET_LE16(data);
- wpa_printf(MSG_DEBUG, "TDLS Setup Confirm " MACSTR " -> "
- MACSTR " (status %d)",
- MAC2STR(src), MAC2STR(dst), status);
-
- if (ieee802_11_parse_elems(data + 3, len - 3, &elems, 1) ==
- ParseFailed || elems.link_id == NULL) {
- /* Need to match TDLS link based on Dialog Token */
- rx_data_tdls_setup_confirm_failure(wt, bssid, src,
- data[2], status);
- return;
- }
- wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
- " initiator STA " MACSTR " responder STA " MACSTR,
- MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
- MAC2STR(elems.link_id + 2 * ETH_ALEN));
-
- tdls = get_tdls(wt, elems.link_id, 1, bssid);
- if (tdls == NULL)
- return;
- if (status)
- tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_CONF_FAIL]++;
- else
- tdls->counters[WLANTEST_TDLS_COUNTER_SETUP_CONF_OK]++;
-
- if (status != WLAN_STATUS_SUCCESS)
- return;
-
- tdls->link_up = 1;
- if (tdls_derive_tpk(tdls, bssid, elems.ftie, elems.ftie_len) < 1) {
- if (elems.ftie == NULL)
- goto remove_reverse;
- return;
- }
- if (tdls_verify_mic(tdls, 3, &elems) == 0) {
- tdls->dialog_token = data[2];
- wpa_printf(MSG_DEBUG, "TDLS: Dialog Token for the link: %u",
- tdls->dialog_token);
- }
-
-remove_reverse:
- /*
- * The TDLS link itself is bidirectional, but there is explicit
- * initiator/responder roles. Remove the other direction of the link
- * (if it exists) to make sure that the link counters are stored for
- * the current TDLS entery.
- */
- os_memcpy(link_id, elems.link_id, ETH_ALEN);
- os_memcpy(link_id + ETH_ALEN, elems.link_id + 2 * ETH_ALEN, ETH_ALEN);
- os_memcpy(link_id + 2 * ETH_ALEN, elems.link_id + ETH_ALEN, ETH_ALEN);
- tdls = get_tdls(wt, link_id, 0, bssid);
- if (tdls) {
- wpa_printf(MSG_DEBUG, "TDLS: Remove reverse link entry");
- tdls_deinit(tdls);
- }
-}
-
-
-static int tdls_verify_mic_teardown(struct wlantest_tdls *tdls, u8 trans_seq,
- const u8 *reason_code,
- struct ieee802_11_elems *elems)
-{
- u8 *buf, *pos;
- int len;
- u8 mic[16];
- int ret;
- const struct rsn_ftie *rx_ftie;
- struct rsn_ftie *tmp_ftie;
-
- if (elems->link_id == NULL || elems->ftie == NULL)
- return -1;
-
- len = 2 + 18 + 2 + 1 + 1 + 2 + elems->ftie_len;
-
- buf = os_zalloc(len);
- if (buf == NULL)
- return -1;
-
- pos = buf;
- /* 1) Link Identifier IE */
- os_memcpy(pos, elems->link_id - 2, 2 + 18);
- pos += 2 + 18;
- /* 2) Reason Code */
- os_memcpy(pos, reason_code, 2);
- pos += 2;
- /* 3) Dialog token */
- *pos++ = tdls->dialog_token;
- /* 4) Transaction Sequence number */
- *pos++ = trans_seq;
- /* 5) FTIE, with the MIC field of the FTIE set to 0 */
- os_memcpy(pos, elems->ftie - 2, 2 + elems->ftie_len);
- pos += 2;
- tmp_ftie = (struct rsn_ftie *) pos;
- os_memset(tmp_ftie->mic, 0, 16);
- pos += elems->ftie_len;
-
- wpa_hexdump(MSG_DEBUG, "TDLS: Data for FTIE MIC", buf, pos - buf);
- wpa_hexdump_key(MSG_DEBUG, "TDLS: KCK", tdls->tpk.kck, 16);
- ret = omac1_aes_128(tdls->tpk.kck, buf, pos - buf, mic);
- os_free(buf);
- if (ret)
- return -1;
- wpa_hexdump(MSG_DEBUG, "TDLS: FTIE MIC", mic, 16);
- rx_ftie = (const struct rsn_ftie *) elems->ftie;
-
- if (os_memcmp(mic, rx_ftie->mic, 16) == 0) {
- wpa_printf(MSG_DEBUG, "TDLS: Valid MIC");
- return 0;
- }
- wpa_printf(MSG_DEBUG, "TDLS: Invalid MIC");
- return -1;
-}
-
-
-static void rx_data_tdls_teardown(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr, const u8 *dst,
- const u8 *src,
- const u8 *data, size_t len)
-{
- u16 reason;
- struct ieee802_11_elems elems;
- struct wlantest_tdls *tdls;
-
- if (len < 2)
- return;
- reason = WPA_GET_LE16(data);
- wpa_printf(MSG_DEBUG, "TDLS Teardown " MACSTR " -> "
- MACSTR " (reason %d)",
- MAC2STR(src), MAC2STR(dst), reason);
-
- if (ieee802_11_parse_elems(data + 2, len - 2, &elems, 1) ==
- ParseFailed || elems.link_id == NULL)
- return;
- wpa_printf(MSG_DEBUG, "TDLS Link Identifier: BSSID " MACSTR
- " initiator STA " MACSTR " responder STA " MACSTR,
- MAC2STR(elems.link_id), MAC2STR(elems.link_id + ETH_ALEN),
- MAC2STR(elems.link_id + 2 * ETH_ALEN));
-
- tdls = get_tdls(wt, elems.link_id, 1, bssid);
- if (tdls) {
- tdls->link_up = 0;
- tdls->counters[WLANTEST_TDLS_COUNTER_TEARDOWN]++;
- tdls_verify_mic_teardown(tdls, 4, data, &elems);
- }
-}
-
-
-static void rx_data_tdls(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr, const u8 *dst, const u8 *src,
- const u8 *data, size_t len)
-{
- /* data contains the payload of a TDLS Action frame */
- if (len < 2 || data[0] != WLAN_ACTION_TDLS) {
- wpa_hexdump(MSG_DEBUG, "Unrecognized encapsulated TDLS frame",
- data, len);
- return;
- }
-
- switch (data[1]) {
- case WLAN_TDLS_SETUP_REQUEST:
- rx_data_tdls_setup_request(wt, bssid, sta_addr, dst, src,
- data + 2, len - 2);
- break;
- case WLAN_TDLS_SETUP_RESPONSE:
- rx_data_tdls_setup_response(wt, bssid, sta_addr, dst, src,
- data + 2, len - 2);
- break;
- case WLAN_TDLS_SETUP_CONFIRM:
- rx_data_tdls_setup_confirm(wt, bssid, sta_addr, dst, src,
- data + 2, len - 2);
- break;
- case WLAN_TDLS_TEARDOWN:
- rx_data_tdls_teardown(wt, bssid, sta_addr, dst, src, data + 2,
- len - 2);
- break;
- case WLAN_TDLS_DISCOVERY_REQUEST:
- wpa_printf(MSG_DEBUG, "TDLS Discovery Request " MACSTR " -> "
- MACSTR, MAC2STR(src), MAC2STR(dst));
- break;
- }
-}
-
-
-void rx_data_80211_encap(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr, const u8 *dst, const u8 *src,
- const u8 *data, size_t len)
-{
- wpa_hexdump(MSG_EXCESSIVE, "802.11 data encap frame", data, len);
- if (len < 1)
- return;
- if (data[0] == 0x02)
- rx_data_tdls(wt, bssid, sta_addr, dst, src, data + 1, len - 1);
-}
diff --git a/wlantest/sta.c b/wlantest/sta.c
deleted file mode 100644
index 115ef8a..0000000
--- a/wlantest/sta.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * STA list
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/defs.h"
-#include "common/ieee802_11_defs.h"
-#include "common/ieee802_11_common.h"
-#include "wlantest.h"
-
-
-struct wlantest_sta * sta_find(struct wlantest_bss *bss, const u8 *addr)
-{
- struct wlantest_sta *sta;
-
- dl_list_for_each(sta, &bss->sta, struct wlantest_sta, list) {
- if (os_memcmp(sta->addr, addr, ETH_ALEN) == 0)
- return sta;
- }
-
- return NULL;
-}
-
-
-struct wlantest_sta * sta_get(struct wlantest_bss *bss, const u8 *addr)
-{
- struct wlantest_sta *sta;
-
- if (addr[0] & 0x01)
- return NULL; /* Skip group addressed frames */
-
- sta = sta_find(bss, addr);
- if (sta)
- return sta;
-
- sta = os_zalloc(sizeof(*sta));
- if (sta == NULL)
- return NULL;
- os_memset(sta->seq_ctrl_to_sta, 0xff, sizeof(sta->seq_ctrl_to_sta));
- os_memset(sta->seq_ctrl_to_ap, 0xff, sizeof(sta->seq_ctrl_to_ap));
- sta->bss = bss;
- os_memcpy(sta->addr, addr, ETH_ALEN);
- dl_list_add(&bss->sta, &sta->list);
- wpa_printf(MSG_DEBUG, "Discovered new STA " MACSTR " in BSS " MACSTR,
- MAC2STR(sta->addr), MAC2STR(bss->bssid));
- return sta;
-}
-
-
-void sta_deinit(struct wlantest_sta *sta)
-{
- dl_list_del(&sta->list);
- os_free(sta->assocreq_ies);
- os_free(sta);
-}
-
-
-void sta_update_assoc(struct wlantest_sta *sta, struct ieee802_11_elems *elems)
-{
- struct wpa_ie_data data;
- struct wlantest_bss *bss = sta->bss;
-
- if (elems->wpa_ie && !bss->wpaie[0]) {
- wpa_printf(MSG_INFO, "WPA IE included in Association Request "
- "frame from " MACSTR " even though BSS does not "
- "use WPA - ignore IE",
- MAC2STR(sta->addr));
- elems->wpa_ie = NULL;
- }
-
- if (elems->rsn_ie && !bss->rsnie[0]) {
- wpa_printf(MSG_INFO, "RSN IE included in Association Request "
- "frame from " MACSTR " even though BSS does not "
- "use RSN - ignore IE",
- MAC2STR(sta->addr));
- elems->rsn_ie = NULL;
- }
-
- if (elems->wpa_ie && elems->rsn_ie) {
- wpa_printf(MSG_INFO, "Both WPA IE and RSN IE included in "
- "Association Request frame from " MACSTR,
- MAC2STR(sta->addr));
- }
-
- if (elems->rsn_ie) {
- wpa_hexdump(MSG_DEBUG, "RSN IE", elems->rsn_ie - 2,
- elems->rsn_ie_len + 2);
- os_memcpy(sta->rsnie, elems->rsn_ie - 2,
- elems->rsn_ie_len + 2);
- if (wpa_parse_wpa_ie_rsn(sta->rsnie, 2 + sta->rsnie[1], &data)
- < 0) {
- wpa_printf(MSG_INFO, "Failed to parse RSN IE from "
- MACSTR, MAC2STR(sta->addr));
- }
- } else if (elems->wpa_ie) {
- wpa_hexdump(MSG_DEBUG, "WPA IE", elems->wpa_ie - 2,
- elems->wpa_ie_len + 2);
- os_memcpy(sta->rsnie, elems->wpa_ie - 2,
- elems->wpa_ie_len + 2);
- if (wpa_parse_wpa_ie_wpa(sta->rsnie, 2 + sta->rsnie[1], &data)
- < 0) {
- wpa_printf(MSG_INFO, "Failed to parse WPA IE from "
- MACSTR, MAC2STR(sta->addr));
- }
- } else {
- sta->rsnie[0] = 0;
- sta->proto = 0;
- sta->pairwise_cipher = 0;
- sta->key_mgmt = 0;
- sta->rsn_capab = 0;
- if (sta->assocreq_capab_info & WLAN_CAPABILITY_PRIVACY)
- sta->pairwise_cipher = WPA_CIPHER_WEP40;
- goto skip_rsn_wpa;
- }
-
- sta->proto = data.proto;
- sta->pairwise_cipher = data.pairwise_cipher;
- sta->key_mgmt = data.key_mgmt;
- sta->rsn_capab = data.capabilities;
- if (bss->proto && (sta->proto & bss->proto) == 0) {
- wpa_printf(MSG_INFO, "Mismatch in WPA/WPA2 proto: STA "
- MACSTR " 0x%x BSS " MACSTR " 0x%x",
- MAC2STR(sta->addr), sta->proto,
- MAC2STR(bss->bssid), bss->proto);
- }
- if (bss->pairwise_cipher &&
- (sta->pairwise_cipher & bss->pairwise_cipher) == 0) {
- wpa_printf(MSG_INFO, "Mismatch in pairwise cipher: STA "
- MACSTR " 0x%x BSS " MACSTR " 0x%x",
- MAC2STR(sta->addr), sta->pairwise_cipher,
- MAC2STR(bss->bssid), bss->pairwise_cipher);
- }
- if (sta->proto && data.group_cipher != bss->group_cipher) {
- wpa_printf(MSG_INFO, "Mismatch in group cipher: STA "
- MACSTR " 0x%x != BSS " MACSTR " 0x%x",
- MAC2STR(sta->addr), data.group_cipher,
- MAC2STR(bss->bssid), bss->group_cipher);
- }
- if ((bss->rsn_capab & WPA_CAPABILITY_MFPR) &&
- !(sta->rsn_capab & WPA_CAPABILITY_MFPC)) {
- wpa_printf(MSG_INFO, "STA " MACSTR " tries to associate "
- "without MFP to BSS " MACSTR " that advertises "
- "MFPR", MAC2STR(sta->addr), MAC2STR(bss->bssid));
- }
-
-skip_rsn_wpa:
- wpa_printf(MSG_INFO, "STA " MACSTR
- " proto=%s%s%s"
- "pairwise=%s%s%s%s"
- "key_mgmt=%s%s%s%s%s%s%s%s"
- "rsn_capab=%s%s%s%s%s",
- MAC2STR(sta->addr),
- sta->proto == 0 ? "OPEN " : "",
- sta->proto & WPA_PROTO_WPA ? "WPA " : "",
- sta->proto & WPA_PROTO_RSN ? "WPA2 " : "",
- sta->pairwise_cipher == 0 ? "N/A " : "",
- sta->pairwise_cipher & WPA_CIPHER_NONE ? "NONE " : "",
- sta->pairwise_cipher & WPA_CIPHER_TKIP ? "TKIP " : "",
- sta->pairwise_cipher & WPA_CIPHER_CCMP ? "CCMP " : "",
- sta->key_mgmt == 0 ? "N/A " : "",
- sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X ? "EAP " : "",
- sta->key_mgmt & WPA_KEY_MGMT_PSK ? "PSK " : "",
- sta->key_mgmt & WPA_KEY_MGMT_WPA_NONE ? "WPA-NONE " : "",
- sta->key_mgmt & WPA_KEY_MGMT_FT_IEEE8021X ? "FT-EAP " : "",
- sta->key_mgmt & WPA_KEY_MGMT_FT_PSK ? "FT-PSK " : "",
- sta->key_mgmt & WPA_KEY_MGMT_IEEE8021X_SHA256 ?
- "EAP-SHA256 " : "",
- sta->key_mgmt & WPA_KEY_MGMT_PSK_SHA256 ?
- "PSK-SHA256 " : "",
- sta->rsn_capab & WPA_CAPABILITY_PREAUTH ? "PREAUTH " : "",
- sta->rsn_capab & WPA_CAPABILITY_NO_PAIRWISE ?
- "NO_PAIRWISE " : "",
- sta->rsn_capab & WPA_CAPABILITY_MFPR ? "MFPR " : "",
- sta->rsn_capab & WPA_CAPABILITY_MFPC ? "MFPC " : "",
- sta->rsn_capab & WPA_CAPABILITY_PEERKEY_ENABLED ?
- "PEERKEY " : "");
-}
diff --git a/wlantest/tkip.c b/wlantest/tkip.c
deleted file mode 100644
index 2d626f3..0000000
--- a/wlantest/tkip.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
- * Temporal Key Integrity Protocol (CCMP)
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/ieee802_11_defs.h"
-#include "wlantest.h"
-
-
-void wep_crypt(u8 *key, u8 *buf, size_t plen);
-
-
-static inline u16 RotR1(u16 val)
-{
- return (val >> 1) | (val << 15);
-}
-
-
-static inline u8 Lo8(u16 val)
-{
- return val & 0xff;
-}
-
-
-static inline u8 Hi8(u16 val)
-{
- return val >> 8;
-}
-
-
-static inline u16 Lo16(u32 val)
-{
- return val & 0xffff;
-}
-
-
-static inline u16 Hi16(u32 val)
-{
- return val >> 16;
-}
-
-
-static inline u16 Mk16(u8 hi, u8 lo)
-{
- return lo | (((u16) hi) << 8);
-}
-
-
-static inline u16 Mk16_le(u16 *v)
-{
- return le_to_host16(*v);
-}
-
-
-static const u16 Sbox[256] =
-{
- 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
- 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
- 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
- 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
- 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
- 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
- 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
- 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
- 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
- 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
- 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
- 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
- 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
- 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
- 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
- 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
- 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
- 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
- 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
- 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
- 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
- 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
- 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
- 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
- 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
- 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
- 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
- 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
- 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
- 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
- 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
- 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
-};
-
-
-static inline u16 _S_(u16 v)
-{
- u16 t = Sbox[Hi8(v)];
- return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
-}
-
-
-#define PHASE1_LOOP_COUNT 8
-
-static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
-{
- int i, j;
-
- /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
- TTAK[0] = Lo16(IV32);
- TTAK[1] = Hi16(IV32);
- TTAK[2] = Mk16(TA[1], TA[0]);
- TTAK[3] = Mk16(TA[3], TA[2]);
- TTAK[4] = Mk16(TA[5], TA[4]);
-
- for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
- j = 2 * (i & 1);
- TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
- TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
- TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
- TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
- TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
- }
-}
-
-
-static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
- u16 IV16)
-{
- u16 PPK[6];
-
- /* Step 1 - make copy of TTAK and bring in TSC */
- PPK[0] = TTAK[0];
- PPK[1] = TTAK[1];
- PPK[2] = TTAK[2];
- PPK[3] = TTAK[3];
- PPK[4] = TTAK[4];
- PPK[5] = TTAK[4] + IV16;
-
- /* Step 2 - 96-bit bijective mixing using S-box */
- PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
- PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
- PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
- PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
- PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
- PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
-
- PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
- PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
- PPK[2] += RotR1(PPK[1]);
- PPK[3] += RotR1(PPK[2]);
- PPK[4] += RotR1(PPK[3]);
- PPK[5] += RotR1(PPK[4]);
-
- /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
- * WEPSeed[0..2] is transmitted as WEP IV */
- WEPSeed[0] = Hi8(IV16);
- WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
- WEPSeed[2] = Lo8(IV16);
- WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
- WPA_PUT_LE16(&WEPSeed[4], PPK[0]);
- WPA_PUT_LE16(&WEPSeed[6], PPK[1]);
- WPA_PUT_LE16(&WEPSeed[8], PPK[2]);
- WPA_PUT_LE16(&WEPSeed[10], PPK[3]);
- WPA_PUT_LE16(&WEPSeed[12], PPK[4]);
- WPA_PUT_LE16(&WEPSeed[14], PPK[5]);
-}
-
-
-static inline u32 rotl(u32 val, int bits)
-{
- return (val << bits) | (val >> (32 - bits));
-}
-
-
-static inline u32 rotr(u32 val, int bits)
-{
- return (val >> bits) | (val << (32 - bits));
-}
-
-
-static inline u32 xswap(u32 val)
-{
- return ((val & 0x00ff00ff) << 8) | ((val & 0xff00ff00) >> 8);
-}
-
-
-#define michael_block(l, r) \
-do { \
- r ^= rotl(l, 17); \
- l += r; \
- r ^= xswap(l); \
- l += r; \
- r ^= rotl(l, 3); \
- l += r; \
- r ^= rotr(l, 2); \
- l += r; \
-} while (0)
-
-
-static void michael_mic(const u8 *key, const u8 *hdr, const u8 *data,
- size_t data_len, u8 *mic)
-{
- u32 l, r;
- int i, blocks, last;
-
- l = WPA_GET_LE32(key);
- r = WPA_GET_LE32(key + 4);
-
- /* Michael MIC pseudo header: DA, SA, 3 x 0, Priority */
- l ^= WPA_GET_LE32(hdr);
- michael_block(l, r);
- l ^= WPA_GET_LE32(&hdr[4]);
- michael_block(l, r);
- l ^= WPA_GET_LE32(&hdr[8]);
- michael_block(l, r);
- l ^= WPA_GET_LE32(&hdr[12]);
- michael_block(l, r);
-
- /* 32-bit blocks of data */
- blocks = data_len / 4;
- last = data_len % 4;
- for (i = 0; i < blocks; i++) {
- l ^= WPA_GET_LE32(&data[4 * i]);
- michael_block(l, r);
- }
-
- /* Last block and padding (0x5a, 4..7 x 0) */
- switch (last) {
- case 0:
- l ^= 0x5a;
- break;
- case 1:
- l ^= data[4 * i] | 0x5a00;
- break;
- case 2:
- l ^= data[4 * i] | (data[4 * i + 1] << 8) | 0x5a0000;
- break;
- case 3:
- l ^= data[4 * i] | (data[4 * i + 1] << 8) |
- (data[4 * i + 2] << 16) | 0x5a000000;
- break;
- }
- michael_block(l, r);
- /* l ^= 0; */
- michael_block(l, r);
-
- WPA_PUT_LE32(mic, l);
- WPA_PUT_LE32(mic + 4, r);
-}
-
-
-static void michael_mic_hdr(const struct ieee80211_hdr *hdr11, u8 *hdr)
-{
- int hdrlen = 24;
- u16 fc = le_to_host16(hdr11->frame_control);
-
- switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) {
- case WLAN_FC_TODS:
- os_memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- os_memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- case WLAN_FC_FROMDS:
- os_memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- os_memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
- break;
- case WLAN_FC_FROMDS | WLAN_FC_TODS:
- os_memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- os_memcpy(hdr + ETH_ALEN, hdr11 + 1, ETH_ALEN); /* SA */
- hdrlen += ETH_ALEN;
- break;
- case 0:
- os_memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- os_memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- }
-
- if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA &&
- (WLAN_FC_GET_STYPE(fc) & 0x08)) {
- const u8 *qos = ((const u8 *) hdr11) + hdrlen;
- hdr[12] = qos[0] & 0x0f; /* priority */
- } else
- hdr[12] = 0; /* priority */
-
- hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
-}
-
-
-u8 * tkip_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
- const u8 *data, size_t data_len, size_t *decrypted_len)
-{
- u16 iv16;
- u32 iv32;
- u16 ttak[5];
- u8 rc4key[16];
- u8 *plain;
- size_t plain_len;
- u32 icv, rx_icv;
- const u8 *mic_key;
- u8 michael_hdr[16];
- u8 mic[8];
- u16 fc = le_to_host16(hdr->frame_control);
-
- if (data_len < 8 + 4)
- return NULL;
-
- iv16 = (data[0] << 8) | data[2];
- iv32 = WPA_GET_LE32(&data[4]);
- wpa_printf(MSG_EXCESSIVE, "TKIP decrypt: iv32=%08x iv16=%04x",
- iv32, iv16);
-
- tkip_mixing_phase1(ttak, tk, hdr->addr2, iv32);
- wpa_hexdump(MSG_EXCESSIVE, "TKIP TTAK", (u8 *) ttak, sizeof(ttak));
- tkip_mixing_phase2(rc4key, tk, ttak, iv16);
- wpa_hexdump(MSG_EXCESSIVE, "TKIP RC4KEY", rc4key, sizeof(rc4key));
-
- plain_len = data_len - 8;
- plain = os_malloc(plain_len);
- if (plain == NULL)
- return NULL;
- os_memcpy(plain, data + 8, plain_len);
- wep_crypt(rc4key, plain, plain_len);
-
- icv = crc32(plain, plain_len - 4);
- rx_icv = WPA_GET_LE32(plain + plain_len - 4);
- if (icv != rx_icv) {
- wpa_printf(MSG_INFO, "TKIP ICV mismatch in frame from " MACSTR,
- MAC2STR(hdr->addr2));
- wpa_printf(MSG_DEBUG, "TKIP calculated ICV %08x received ICV "
- "%08x", icv, rx_icv);
- os_free(plain);
- return NULL;
- }
- plain_len -= 4;
-
- /* TODO: MSDU reassembly */
-
- if (plain_len < 8) {
- wpa_printf(MSG_INFO, "TKIP: Not enough room for Michael MIC "
- "in a frame from " MACSTR, MAC2STR(hdr->addr2));
- os_free(plain);
- return NULL;
- }
-
- michael_mic_hdr(hdr, michael_hdr);
- mic_key = tk + ((fc & WLAN_FC_FROMDS) ? 16 : 24);
- michael_mic(mic_key, michael_hdr, plain, plain_len - 8, mic);
- if (os_memcmp(mic, plain + plain_len - 8, 8) != 0) {
- wpa_printf(MSG_INFO, "TKIP: Michael MIC mismatch in a frame "
- "from " MACSTR, MAC2STR(hdr->addr2));
- wpa_hexdump(MSG_DEBUG, "TKIP: Calculated MIC", mic, 8);
- wpa_hexdump(MSG_DEBUG, "TKIP: Received MIC",
- plain + plain_len - 8, 8);
- os_free(plain);
- return NULL;
- }
-
- *decrypted_len = plain_len - 8;
- return plain;
-}
-
-
-void tkip_get_pn(u8 *pn, const u8 *data)
-{
- pn[0] = data[7]; /* PN5 */
- pn[1] = data[6]; /* PN4 */
- pn[2] = data[5]; /* PN3 */
- pn[3] = data[4]; /* PN2 */
- pn[4] = data[0]; /* PN1 */
- pn[5] = data[2]; /* PN0 */
-}
-
-
-u8 * tkip_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
- u8 *pn, int keyid, size_t *encrypted_len)
-{
- /* TODO */
- return NULL;
-}
diff --git a/wlantest/wep.c b/wlantest/wep.c
deleted file mode 100644
index c4137f3..0000000
--- a/wlantest/wep.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Wired Equivalent Privacy (WEP)
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "common/ieee802_11_defs.h"
-#include "wlantest.h"
-
-
-void wep_crypt(u8 *key, u8 *buf, size_t plen)
-{
- u32 i, j, k;
- u8 S[256];
-#define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0)
- u8 *pos;
-
- /* Setup RC4 state */
- for (i = 0; i < 256; i++)
- S[i] = i;
- j = 0;
- for (i = 0; i < 256; i++) {
- j = (j + S[i] + key[i & 0x0f]) & 0xff;
- S_SWAP(i, j);
- }
-
- /* Apply RC4 to data */
- pos = buf;
- i = j = 0;
- for (k = 0; k < plen; k++) {
- i = (i + 1) & 0xff;
- j = (j + S[i]) & 0xff;
- S_SWAP(i, j);
- *pos ^= S[(S[i] + S[j]) & 0xff];
- pos++;
- }
-}
-
-
-static int try_wep(const u8 *key, size_t key_len, const u8 *data,
- size_t data_len, u8 *plain)
-{
- u32 icv, rx_icv;
- u8 k[16];
- int i, j;
-
- for (i = 0, j = 0; i < sizeof(k); i++) {
- k[i] = key[j];
- j++;
- if (j >= key_len)
- j = 0;
- }
-
- os_memcpy(plain, data, data_len);
- wep_crypt(k, plain, data_len);
- icv = crc32(plain, data_len - 4);
- rx_icv = WPA_GET_LE32(plain + data_len - 4);
- if (icv != rx_icv)
- return -1;
-
- return 0;
-}
-
-
-u8 * wep_decrypt(struct wlantest *wt, const struct ieee80211_hdr *hdr,
- const u8 *data, size_t data_len, size_t *decrypted_len)
-{
- u8 *plain;
- struct wlantest_wep *w;
- int found = 0;
- u8 key[16];
-
- if (dl_list_empty(&wt->wep))
- return NULL;
-
- if (data_len < 4 + 4)
- return NULL;
- plain = os_malloc(data_len - 4);
- if (plain == NULL)
- return NULL;
-
- dl_list_for_each(w, &wt->wep, struct wlantest_wep, list) {
- os_memcpy(key, data, 3);
- os_memcpy(key + 3, w->key, w->key_len);
- if (try_wep(key, 3 + w->key_len, data + 4, data_len - 4, plain)
- == 0) {
- found = 1;
- break;
- }
- }
- if (!found) {
- os_free(plain);
- return NULL;
- }
-
- *decrypted_len = data_len - 4 - 4;
- return plain;
-}
diff --git a/wlantest/wired.c b/wlantest/wired.c
deleted file mode 100644
index 77a395f..0000000
--- a/wlantest/wired.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Received frame processing for wired interface
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include <net/ethernet.h>
-#include <netinet/ip.h>
-#include <netinet/udp.h>
-
-#include "utils/common.h"
-#include "radius/radius.h"
-#include "wlantest.h"
-
-
-static struct wlantest_radius * radius_get(struct wlantest *wt, u32 srv,
- u32 cli)
-{
- struct wlantest_radius *r;
-
- dl_list_for_each(r, &wt->radius, struct wlantest_radius, list) {
- if (r->srv == srv && r->cli == cli)
- return r;
- }
-
- r = os_zalloc(sizeof(*r));
- if (r == NULL)
- return NULL;
-
- r->srv = srv;
- r->cli = cli;
- dl_list_add(&wt->radius, &r->list);
-
- return r;
-}
-
-
-static const char * radius_code_string(u8 code)
-{
- switch (code) {
- case RADIUS_CODE_ACCESS_REQUEST:
- return "Access-Request";
- case RADIUS_CODE_ACCESS_ACCEPT:
- return "Access-Accept";
- case RADIUS_CODE_ACCESS_REJECT:
- return "Access-Reject";
- case RADIUS_CODE_ACCOUNTING_REQUEST:
- return "Accounting-Request";
- case RADIUS_CODE_ACCOUNTING_RESPONSE:
- return "Accounting-Response";
- case RADIUS_CODE_ACCESS_CHALLENGE:
- return "Access-Challenge";
- case RADIUS_CODE_STATUS_SERVER:
- return "Status-Server";
- case RADIUS_CODE_STATUS_CLIENT:
- return "Status-Client";
- case RADIUS_CODE_RESERVED:
- return "Reserved";
- default:
- return "?Unknown?";
- }
-}
-
-
-static void process_radius_access_request(struct wlantest *wt, u32 dst,
- u32 src, const u8 *data, size_t len)
-{
- struct radius_msg *msg;
- struct wlantest_radius *r;
-
- msg = radius_msg_parse(data, len);
- if (msg == NULL) {
- wpa_printf(MSG_DEBUG, "Failed to parse RADIUS Access-Request");
- return;
- }
-
- r = radius_get(wt, dst, src);
- if (r) {
- radius_msg_free(r->last_req);
- r->last_req = msg;
- return;
- }
- radius_msg_free(msg);
-}
-
-
-static void wlantest_add_pmk(struct wlantest *wt, const u8 *pmk)
-{
- struct wlantest_pmk *p;
-
- p = os_zalloc(sizeof(*p));
- if (p == NULL)
- return;
- os_memcpy(p->pmk, pmk, 32);
- dl_list_add(&wt->pmk, &p->list);
- wpa_hexdump(MSG_INFO, "Add PMK", pmk, 32);
-}
-
-
-static void process_radius_access_accept(struct wlantest *wt, u32 dst, u32 src,
- const u8 *data, size_t len)
-{
- struct radius_msg *msg;
- struct wlantest_radius *r;
- struct radius_ms_mppe_keys *keys;
- struct wlantest_radius_secret *s;
-
- r = radius_get(wt, src, dst);
- if (r == NULL || r->last_req == NULL) {
- wpa_printf(MSG_DEBUG, "No RADIUS Access-Challenge found for "
- "decrypting Access-Accept keys");
- return;
- }
-
- msg = radius_msg_parse(data, len);
- if (msg == NULL) {
- wpa_printf(MSG_DEBUG, "Failed to parse RADIUS Access-Accept");
- return;
- }
-
- dl_list_for_each(s, &wt->secret, struct wlantest_radius_secret, list) {
- int found = 0;
- keys = radius_msg_get_ms_keys(msg, r->last_req,
- (u8 *) s->secret,
- os_strlen(s->secret));
- if (keys && keys->send && keys->recv) {
- u8 pmk[32];
- wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Send-Key",
- keys->send, keys->send_len);
- wpa_hexdump_key(MSG_DEBUG, "MS-MPPE-Recv-Key",
- keys->recv, keys->recv_len);
- os_memcpy(pmk, keys->recv,
- keys->recv_len > 32 ? 32 : keys->recv_len);
- if (keys->recv_len < 32) {
- os_memcpy(pmk + keys->recv_len,
- keys->send,
- keys->recv_len + keys->send_len > 32
- ? 32 : 32 - keys->recv_len);
- }
- wlantest_add_pmk(wt, pmk);
- found = 1;
- }
-
- if (keys) {
- os_free(keys->send);
- os_free(keys->recv);
- os_free(keys);
- }
-
- if (found)
- break;
- }
-
- radius_msg_free(msg);
-}
-
-
-static void process_radius(struct wlantest *wt, u32 dst, u16 dport, u32 src,
- u16 sport, const u8 *data, size_t len)
-{
- struct in_addr addr;
- char buf[20];
- const struct radius_hdr *hdr;
- u16 rlen;
-
- if (len < sizeof(*hdr))
- return;
- hdr = (const struct radius_hdr *) data;
- rlen = be_to_host16(hdr->length);
- if (len < rlen)
- return;
- if (len > rlen)
- len = rlen;
-
- addr.s_addr = dst;
- snprintf(buf, sizeof(buf), "%s", inet_ntoa(addr));
-
- addr.s_addr = src;
- wpa_printf(MSG_DEBUG, "RADIUS %s:%u -> %s:%u id=%u %s",
- inet_ntoa(addr), sport, buf, dport, hdr->identifier,
- radius_code_string(hdr->code));
-
- switch (hdr->code) {
- case RADIUS_CODE_ACCESS_REQUEST:
- process_radius_access_request(wt, dst, src, data, len);
- break;
- case RADIUS_CODE_ACCESS_ACCEPT:
- process_radius_access_accept(wt, dst, src, data, len);
- break;
- }
-}
-
-
-static void process_udp(struct wlantest *wt, u32 dst, u32 src,
- const u8 *data, size_t len)
-{
- const struct udphdr *udp;
- u16 sport, dport, ulen;
- const u8 *payload;
- size_t plen;
-
- if (len < sizeof(*udp))
- return;
- udp = (const struct udphdr *) data;
- /* TODO: check UDP checksum */
- sport = be_to_host16(udp->source);
- dport = be_to_host16(udp->dest);
- ulen = be_to_host16(udp->len);
-
- if (ulen > len)
- return;
- if (len < ulen)
- len = ulen;
-
- payload = (const u8 *) (udp + 1);
- plen = len - sizeof(*udp);
-
- if (sport == 1812 || dport == 1812)
- process_radius(wt, dst, dport, src, sport, payload, plen);
-}
-
-
-static void process_ipv4(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct iphdr *ip;
- const u8 *payload;
- size_t plen;
- u16 frag_off, tot_len;
-
- if (len < sizeof(*ip))
- return;
-
- ip = (const struct iphdr *) data;
- if (ip->version != 4)
- return;
- if (ip->ihl < 5)
- return;
-
- /* TODO: check header checksum in ip->check */
-
- frag_off = be_to_host16(ip->frag_off);
- if (frag_off & 0x1fff) {
- wpa_printf(MSG_EXCESSIVE, "IP fragment reassembly not yet "
- "supported");
- return;
- }
-
- tot_len = be_to_host16(ip->tot_len);
- if (tot_len > len)
- return;
- if (tot_len < len)
- len = tot_len;
-
- payload = data + 4 * ip->ihl;
- plen = len - 4 * ip->ihl;
- if (payload + plen > data + len)
- return;
-
- switch (ip->protocol) {
- case IPPROTO_UDP:
- process_udp(wt, ip->daddr, ip->saddr, payload, plen);
- break;
- }
-}
-
-
-void wlantest_process_wired(struct wlantest *wt, const u8 *data, size_t len)
-{
- const struct ether_header *eth;
- u16 ethertype;
-
- wpa_hexdump(MSG_EXCESSIVE, "Process wired frame", data, len);
-
- if (len < sizeof(*eth))
- return;
-
- eth = (const struct ether_header *) data;
- ethertype = be_to_host16(eth->ether_type);
-
- switch (ethertype) {
- case ETHERTYPE_IP:
- process_ipv4(wt, data + sizeof(*eth), len - sizeof(*eth));
- break;
- }
-}
diff --git a/wlantest/wlantest.c b/wlantest/wlantest.c
deleted file mode 100644
index 094ed17..0000000
--- a/wlantest/wlantest.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * wlantest - IEEE 802.11 protocol monitoring and testing tool
- * Copyright (c) 2010-2011, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "wlantest.h"
-
-
-extern int wpa_debug_level;
-extern int wpa_debug_show_keys;
-
-
-static void wlantest_terminate(int sig, void *signal_ctx)
-{
- eloop_terminate();
-}
-
-
-static void usage(void)
-{
- printf("wlantest [-cddhqq] [-i<ifname>] [-r<pcap file>] "
- "[-p<passphrase>]\n"
- " [-I<wired ifname>] [-R<wired pcap file>] "
- "[-P<RADIUS shared secret>]\n"
- " [-w<write pcap file>] [-f<MSK/PMK file>]\n");
-}
-
-
-static void passphrase_deinit(struct wlantest_passphrase *p)
-{
- dl_list_del(&p->list);
- os_free(p);
-}
-
-
-static void secret_deinit(struct wlantest_radius_secret *r)
-{
- dl_list_del(&r->list);
- os_free(r);
-}
-
-
-static void wlantest_init(struct wlantest *wt)
-{
- int i;
- os_memset(wt, 0, sizeof(*wt));
- wt->monitor_sock = -1;
- wt->ctrl_sock = -1;
- for (i = 0; i < MAX_CTRL_CONNECTIONS; i++)
- wt->ctrl_socks[i] = -1;
- dl_list_init(&wt->passphrase);
- dl_list_init(&wt->bss);
- dl_list_init(&wt->secret);
- dl_list_init(&wt->radius);
- dl_list_init(&wt->pmk);
- dl_list_init(&wt->wep);
-}
-
-
-void radius_deinit(struct wlantest_radius *r)
-{
- dl_list_del(&r->list);
- os_free(r);
-}
-
-
-static void wlantest_deinit(struct wlantest *wt)
-{
- struct wlantest_passphrase *p, *pn;
- struct wlantest_radius_secret *s, *sn;
- struct wlantest_radius *r, *rn;
- struct wlantest_pmk *pmk, *np;
- struct wlantest_wep *wep, *nw;
-
- if (wt->ctrl_sock >= 0)
- ctrl_deinit(wt);
- if (wt->monitor_sock >= 0)
- monitor_deinit(wt);
- bss_flush(wt);
- dl_list_for_each_safe(p, pn, &wt->passphrase,
- struct wlantest_passphrase, list)
- passphrase_deinit(p);
- dl_list_for_each_safe(s, sn, &wt->secret,
- struct wlantest_radius_secret, list)
- secret_deinit(s);
- dl_list_for_each_safe(r, rn, &wt->radius, struct wlantest_radius, list)
- radius_deinit(r);
- dl_list_for_each_safe(pmk, np, &wt->pmk, struct wlantest_pmk, list)
- pmk_deinit(pmk);
- dl_list_for_each_safe(wep, nw, &wt->wep, struct wlantest_wep, list)
- os_free(wep);
- write_pcap_deinit(wt);
-}
-
-
-static void add_passphrase(struct wlantest *wt, const char *passphrase)
-{
- struct wlantest_passphrase *p;
- size_t len = os_strlen(passphrase);
-
- if (len < 8 || len > 63)
- return;
- p = os_zalloc(sizeof(*p));
- if (p == NULL)
- return;
- os_memcpy(p->passphrase, passphrase, len);
- dl_list_add(&wt->passphrase, &p->list);
-}
-
-
-static void add_secret(struct wlantest *wt, const char *secret)
-{
- struct wlantest_radius_secret *s;
- size_t len = os_strlen(secret);
-
- if (len >= MAX_RADIUS_SECRET_LEN)
- return;
- s = os_zalloc(sizeof(*s));
- if (s == NULL)
- return;
- os_memcpy(s->secret, secret, len);
- dl_list_add(&wt->secret, &s->list);
-}
-
-
-static int add_pmk_file(struct wlantest *wt, const char *pmk_file)
-{
- FILE *f;
- u8 pmk[32];
- char buf[300], *pos;
- struct wlantest_pmk *p;
-
- f = fopen(pmk_file, "r");
- if (f == NULL) {
- wpa_printf(MSG_ERROR, "Could not open '%s'", pmk_file);
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), f)) {
- pos = buf;
- while (*pos && *pos != '\r' && *pos != '\n')
- pos++;
- *pos = '\0';
- if (pos - buf < 2 * 32)
- continue;
- if (hexstr2bin(buf, pmk, 32) < 0)
- continue;
- p = os_zalloc(sizeof(*p));
- if (p == NULL)
- break;
- os_memcpy(p->pmk, pmk, 32);
- dl_list_add(&wt->pmk, &p->list);
- wpa_hexdump(MSG_DEBUG, "Added PMK from file", pmk, 32);
- }
-
- fclose(f);
- return 0;
-}
-
-
-int add_wep(struct wlantest *wt, const char *key)
-{
- struct wlantest_wep *w;
- size_t len = os_strlen(key);
-
- if (len != 2 * 5 && len != 2 * 13) {
- wpa_printf(MSG_INFO, "Invalid WEP key '%s'", key);
- return -1;
- }
- w = os_zalloc(sizeof(*w));
- if (w == NULL)
- return -1;
- if (hexstr2bin(key, w->key, len / 2) < 0) {
- os_free(w);
- wpa_printf(MSG_INFO, "Invalid WEP key '%s'", key);
- return -1;
- }
- w->key_len = len / 2;
- dl_list_add(&wt->wep, &w->list);
- return 0;
-}
-
-
-int main(int argc, char *argv[])
-{
- int c;
- const char *read_file = NULL;
- const char *read_wired_file = NULL;
- const char *write_file = NULL;
- const char *ifname = NULL;
- const char *ifname_wired = NULL;
- struct wlantest wt;
- int ctrl_iface = 0;
-
- wpa_debug_level = MSG_INFO;
- wpa_debug_show_keys = 1;
-
- if (os_program_init())
- return -1;
-
- wlantest_init(&wt);
-
- for (;;) {
- c = getopt(argc, argv, "cdf:hi:I:p:P:qr:R:w:W:");
- if (c < 0)
- break;
- switch (c) {
- case 'c':
- ctrl_iface = 1;
- break;
- case 'd':
- if (wpa_debug_level > 0)
- wpa_debug_level--;
- break;
- case 'f':
- if (add_pmk_file(&wt, optarg) < 0)
- return -1;
- break;
- case 'h':
- usage();
- return 0;
- case 'i':
- ifname = optarg;
- break;
- case 'I':
- ifname_wired = optarg;
- break;
- case 'p':
- add_passphrase(&wt, optarg);
- break;
- case 'P':
- add_secret(&wt, optarg);
- break;
- case 'q':
- wpa_debug_level++;
- break;
- case 'r':
- read_file = optarg;
- break;
- case 'R':
- read_wired_file = optarg;
- break;
- case 'w':
- write_file = optarg;
- break;
- case 'W':
- if (add_wep(&wt, optarg) < 0)
- return -1;
- break;
- default:
- usage();
- return -1;
- }
- }
-
- if (ifname == NULL && ifname_wired == NULL &&
- read_file == NULL && read_wired_file == NULL) {
- usage();
- return 0;
- }
-
- if (eloop_init())
- return -1;
-
- if (write_file && write_pcap_init(&wt, write_file) < 0)
- return -1;
-
- if (read_wired_file && read_wired_cap_file(&wt, read_wired_file) < 0)
- return -1;
-
- if (read_file && read_cap_file(&wt, read_file) < 0)
- return -1;
-
- if (ifname && monitor_init(&wt, ifname) < 0)
- return -1;
-
- if (ifname_wired && monitor_init_wired(&wt, ifname_wired) < 0)
- return -1;
-
- if (ctrl_iface && ctrl_init(&wt) < 0)
- return -1;
-
- eloop_register_signal_terminate(wlantest_terminate, &wt);
-
- eloop_run();
-
- wpa_printf(MSG_INFO, "Processed: rx_mgmt=%u rx_ctrl=%u rx_data=%u "
- "fcs_error=%u",
- wt.rx_mgmt, wt.rx_ctrl, wt.rx_data, wt.fcs_error);
-
- wlantest_deinit(&wt);
-
- eloop_destroy();
- os_program_deinit();
-
- return 0;
-}
diff --git a/wlantest/wlantest.h b/wlantest/wlantest.h
deleted file mode 100644
index de8bc65..0000000
--- a/wlantest/wlantest.h
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * wlantest - IEEE 802.11 protocol monitoring and testing tool
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WLANTEST_H
-#define WLANTEST_H
-
-#include "utils/list.h"
-#include "common/wpa_common.h"
-#include "wlantest_ctrl.h"
-
-struct ieee802_11_elems;
-struct radius_msg;
-struct ieee80211_hdr;
-struct wlantest_bss;
-
-#define MAX_RADIUS_SECRET_LEN 128
-
-struct wlantest_radius_secret {
- struct dl_list list;
- char secret[MAX_RADIUS_SECRET_LEN];
-};
-
-struct wlantest_passphrase {
- struct dl_list list;
- char passphrase[64];
- u8 ssid[32];
- size_t ssid_len;
- u8 bssid[ETH_ALEN];
-};
-
-struct wlantest_pmk {
- struct dl_list list;
- u8 pmk[32];
-};
-
-struct wlantest_wep {
- struct dl_list list;
- size_t key_len;
- u8 key[13];
-};
-
-struct wlantest_sta {
- struct dl_list list;
- struct wlantest_bss *bss;
- u8 addr[ETH_ALEN];
- enum {
- STATE1 /* not authenticated */,
- STATE2 /* authenticated */,
- STATE3 /* associated */
- } state;
- u16 aid;
- u8 rsnie[257]; /* WPA/RSN IE */
- int proto;
- int pairwise_cipher;
- int group_cipher;
- int key_mgmt;
- int rsn_capab;
- u8 anonce[32]; /* ANonce from the previous EAPOL-Key msg 1/4 or 3/4 */
- u8 snonce[32]; /* SNonce from the previous EAPOL-Key msg 2/4 */
- struct wpa_ptk ptk; /* Derived PTK */
- int ptk_set;
- struct wpa_ptk tptk; /* Derived PTK during rekeying */
- int tptk_set;
- u8 rsc_tods[16 + 1][6];
- u8 rsc_fromds[16 + 1][6];
- u8 ap_sa_query_tr[2];
- u8 sta_sa_query_tr[2];
- u32 counters[NUM_WLANTEST_STA_COUNTER];
- u16 assocreq_capab_info;
- u16 assocreq_listen_int;
- u8 *assocreq_ies;
- size_t assocreq_ies_len;
-
- /* Last ICMP Echo request information */
- u32 icmp_echo_req_src;
- u32 icmp_echo_req_dst;
- u16 icmp_echo_req_id;
- u16 icmp_echo_req_seq;
-
- le16 seq_ctrl_to_sta[17];
- le16 seq_ctrl_to_ap[17];
-
- int pwrmgt;
- int pspoll;
-
- u8 gtk[32];
- size_t gtk_len;
- int gtk_idx;
-};
-
-struct wlantest_tdls {
- struct dl_list list;
- struct wlantest_sta *init;
- struct wlantest_sta *resp;
- struct tpk {
- u8 kck[16];
- u8 tk[16];
- } tpk;
- int link_up;
- u8 dialog_token;
- u8 rsc_init[16 + 1][6];
- u8 rsc_resp[16 + 1][6];
- u32 counters[NUM_WLANTEST_TDLS_COUNTER];
-};
-
-struct wlantest_bss {
- struct dl_list list;
- u8 bssid[ETH_ALEN];
- u16 capab_info;
- u16 prev_capab_info;
- u8 ssid[32];
- size_t ssid_len;
- int proberesp_seen;
- int parse_error_reported;
- u8 wpaie[257];
- u8 rsnie[257];
- int proto;
- int pairwise_cipher;
- int group_cipher;
- int mgmt_group_cipher;
- int key_mgmt;
- int rsn_capab;
- struct dl_list sta; /* struct wlantest_sta */
- struct dl_list pmk; /* struct wlantest_pmk */
- u8 gtk[4][32];
- size_t gtk_len[4];
- int gtk_idx;
- u8 rsc[4][6];
- u8 igtk[6][16];
- int igtk_set[6];
- int igtk_idx;
- u8 ipn[6][6];
- u32 counters[NUM_WLANTEST_BSS_COUNTER];
- struct dl_list tdls; /* struct wlantest_tdls */
-};
-
-struct wlantest_radius {
- struct dl_list list;
- u32 srv;
- u32 cli;
- struct radius_msg *last_req;
-};
-
-
-#define MAX_CTRL_CONNECTIONS 10
-
-struct wlantest {
- int monitor_sock;
- int monitor_wired;
-
- int ctrl_sock;
- int ctrl_socks[MAX_CTRL_CONNECTIONS];
-
- struct dl_list passphrase; /* struct wlantest_passphrase */
- struct dl_list bss; /* struct wlantest_bss */
- struct dl_list secret; /* struct wlantest_radius_secret */
- struct dl_list radius; /* struct wlantest_radius */
- struct dl_list pmk; /* struct wlantest_pmk */
- struct dl_list wep; /* struct wlantest_wep */
-
- unsigned int rx_mgmt;
- unsigned int rx_ctrl;
- unsigned int rx_data;
- unsigned int fcs_error;
-
- void *write_pcap; /* pcap_t* */
- void *write_pcap_dumper; /* pcpa_dumper_t */
- struct timeval write_pcap_time;
-
- u8 last_hdr[30];
- size_t last_len;
- int last_mgmt_valid;
-};
-
-int add_wep(struct wlantest *wt, const char *key);
-int read_cap_file(struct wlantest *wt, const char *fname);
-int read_wired_cap_file(struct wlantest *wt, const char *fname);
-int write_pcap_init(struct wlantest *wt, const char *fname);
-void write_pcap_deinit(struct wlantest *wt);
-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_80211(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);
-int monitor_init_wired(struct wlantest *wt, const char *ifname);
-void monitor_deinit(struct wlantest *wt);
-void rx_mgmt(struct wlantest *wt, const u8 *data, size_t len);
-void rx_mgmt_ack(struct wlantest *wt, const struct ieee80211_hdr *hdr);
-void rx_data(struct wlantest *wt, const u8 *data, size_t len);
-void rx_data_eapol(struct wlantest *wt, const u8 *dst, const u8 *src,
- const u8 *data, size_t len, int prot);
-void rx_data_ip(struct wlantest *wt, const u8 *bssid, const u8 *sta_addr,
- const u8 *dst, const u8 *src, const u8 *data, size_t len,
- const u8 *peer_addr);
-void rx_data_80211_encap(struct wlantest *wt, const u8 *bssid,
- const u8 *sta_addr, const u8 *dst, const u8 *src,
- const u8 *data, size_t len);
-
-struct wlantest_bss * bss_find(struct wlantest *wt, const u8 *bssid);
-struct wlantest_bss * bss_get(struct wlantest *wt, const u8 *bssid);
-void bss_deinit(struct wlantest_bss *bss);
-void bss_update(struct wlantest *wt, struct wlantest_bss *bss,
- struct ieee802_11_elems *elems);
-void bss_flush(struct wlantest *wt);
-int bss_add_pmk_from_passphrase(struct wlantest_bss *bss,
- const char *passphrase);
-void pmk_deinit(struct wlantest_pmk *pmk);
-void tdls_deinit(struct wlantest_tdls *tdls);
-
-struct wlantest_sta * sta_find(struct wlantest_bss *bss, const u8 *addr);
-struct wlantest_sta * sta_get(struct wlantest_bss *bss, const u8 *addr);
-void sta_deinit(struct wlantest_sta *sta);
-void sta_update_assoc(struct wlantest_sta *sta,
- struct ieee802_11_elems *elems);
-
-u8 * ccmp_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
- const u8 *data, size_t data_len, size_t *decrypted_len);
-u8 * ccmp_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
- u8 *pn, int keyid, size_t *encrypted_len);
-void ccmp_get_pn(u8 *pn, const u8 *data);
-
-u8 * tkip_decrypt(const u8 *tk, const struct ieee80211_hdr *hdr,
- const u8 *data, size_t data_len, size_t *decrypted_len);
-u8 * tkip_encrypt(const u8 *tk, u8 *frame, size_t len, size_t hdrlen, u8 *qos,
- u8 *pn, int keyid, size_t *encrypted_len);
-void tkip_get_pn(u8 *pn, const u8 *data);
-
-u8 * wep_decrypt(struct wlantest *wt, const struct ieee80211_hdr *hdr,
- const u8 *data, size_t data_len, size_t *decrypted_len);
-
-int ctrl_init(struct wlantest *wt);
-void ctrl_deinit(struct wlantest *wt);
-
-int wlantest_inject(struct wlantest *wt, struct wlantest_bss *bss,
- struct wlantest_sta *sta, u8 *frame, size_t len,
- enum wlantest_inject_protection prot);
-
-#endif /* WLANTEST_H */
diff --git a/wlantest/wlantest_cli.c b/wlantest/wlantest_cli.c
deleted file mode 100644
index ce95081..0000000
--- a/wlantest/wlantest_cli.c
+++ /dev/null
@@ -1,1714 +0,0 @@
-/*
- * wlantest controller
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include <sys/un.h>
-
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/edit.h"
-#include "wlantest_ctrl.h"
-
-
-static int get_cmd_arg_num(const char *str, int pos)
-{
- int arg = 0, i;
-
- for (i = 0; i <= pos; i++) {
- if (str[i] != ' ') {
- arg++;
- while (i <= pos && str[i] != ' ')
- i++;
- }
- }
-
- if (arg > 0)
- arg--;
- return arg;
-}
-
-
-static int get_prev_arg_pos(const char *str, int pos)
-{
- while (pos > 0 && str[pos - 1] != ' ')
- pos--;
- while (pos > 0 && str[pos - 1] == ' ')
- pos--;
- while (pos > 0 && str[pos - 1] != ' ')
- pos--;
- return pos;
-}
-
-
-static u8 * attr_get(u8 *buf, size_t buflen, enum wlantest_ctrl_attr attr,
- size_t *len)
-{
- u8 *pos = buf;
-
- while (pos + 8 <= buf + buflen) {
- enum wlantest_ctrl_attr a;
- size_t alen;
- a = WPA_GET_BE32(pos);
- pos += 4;
- alen = WPA_GET_BE32(pos);
- pos += 4;
- if (pos + alen > buf + buflen) {
- printf("Invalid control message attribute\n");
- return NULL;
- }
- if (a == attr) {
- *len = alen;
- return pos;
- }
- pos += alen;
- }
-
- return NULL;
-}
-
-
-static u8 * attr_hdr_add(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
- size_t len)
-{
- if (pos == NULL || end - pos < 8 + len)
- return NULL;
- WPA_PUT_BE32(pos, attr);
- pos += 4;
- WPA_PUT_BE32(pos, len);
- pos += 4;
- return pos;
-}
-
-
-static u8 * attr_add_str(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
- const char *str)
-{
- size_t len = os_strlen(str);
-
- if (pos == NULL || end - pos < 8 + len)
- return NULL;
- WPA_PUT_BE32(pos, attr);
- pos += 4;
- WPA_PUT_BE32(pos, len);
- pos += 4;
- os_memcpy(pos, str, len);
- pos += len;
- return pos;
-}
-
-
-static u8 * attr_add_be32(u8 *pos, u8 *end, enum wlantest_ctrl_attr attr,
- u32 val)
-{
- if (pos == NULL || end - pos < 12)
- return NULL;
- WPA_PUT_BE32(pos, attr);
- pos += 4;
- WPA_PUT_BE32(pos, 4);
- pos += 4;
- WPA_PUT_BE32(pos, val);
- pos += 4;
- return pos;
-}
-
-
-static int cmd_send_and_recv(int s, const u8 *cmd, size_t cmd_len,
- u8 *resp, size_t max_resp_len)
-{
- int res;
- enum wlantest_ctrl_cmd cmd_resp;
-
- if (send(s, cmd, cmd_len, 0) < 0)
- return -1;
- res = recv(s, resp, max_resp_len, 0);
- if (res < 4)
- return -1;
-
- cmd_resp = WPA_GET_BE32(resp);
- if (cmd_resp == WLANTEST_CTRL_SUCCESS)
- return res;
-
- if (cmd_resp == WLANTEST_CTRL_UNKNOWN_CMD)
- printf("Unknown command\n");
- else if (cmd_resp == WLANTEST_CTRL_INVALID_CMD)
- printf("Invalid command\n");
-
- return -1;
-}
-
-
-static int cmd_simple(int s, enum wlantest_ctrl_cmd cmd)
-{
- u8 buf[4];
- int res;
- WPA_PUT_BE32(buf, cmd);
- res = cmd_send_and_recv(s, buf, sizeof(buf), buf, sizeof(buf));
- return res < 0 ? -1 : 0;
-}
-
-
-static char ** get_bssid_list(int s)
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[4];
- u8 *bssid;
- size_t len;
- int rlen, i;
- char **res;
-
- WPA_PUT_BE32(buf, WLANTEST_CTRL_LIST_BSS);
- rlen = cmd_send_and_recv(s, buf, sizeof(buf), resp, sizeof(resp));
- if (rlen < 0)
- return NULL;
-
- bssid = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_BSSID, &len);
- if (bssid == NULL)
- return NULL;
-
- res = os_zalloc((len / ETH_ALEN + 1) * sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; i < len / ETH_ALEN; i++) {
- res[i] = os_zalloc(18);
- if (res[i] == NULL)
- break;
- os_snprintf(res[i], 18, MACSTR, MAC2STR(bssid + ETH_ALEN * i));
- }
-
- return res;
-}
-
-
-static char ** get_sta_list(int s, const u8 *bssid, int add_bcast)
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *pos, *end;
- u8 *addr;
- size_t len;
- int rlen, i;
- char **res;
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_LIST_STA);
- pos += 4;
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
- os_memcpy(pos, bssid, ETH_ALEN);
- pos += ETH_ALEN;
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return NULL;
-
- addr = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_STA_ADDR, &len);
- if (addr == NULL)
- return NULL;
-
- res = os_zalloc((len / ETH_ALEN + 1 + add_bcast) * sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; i < len / ETH_ALEN; i++) {
- res[i] = os_zalloc(18);
- if (res[i] == NULL)
- break;
- os_snprintf(res[i], 18, MACSTR, MAC2STR(addr + ETH_ALEN * i));
- }
- if (add_bcast)
- res[i] = os_strdup("ff:ff:ff:ff:ff:ff");
-
- return res;
-}
-
-
-static int cmd_ping(int s, int argc, char *argv[])
-{
- int res = cmd_simple(s, WLANTEST_CTRL_PING);
- if (res == 0)
- printf("PONG\n");
- return res == 0;
-}
-
-
-static int cmd_terminate(int s, int argc, char *argv[])
-{
- return cmd_simple(s, WLANTEST_CTRL_TERMINATE);
-}
-
-
-static int cmd_list_bss(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[4];
- u8 *bssid;
- size_t len;
- int rlen, i;
-
- WPA_PUT_BE32(buf, WLANTEST_CTRL_LIST_BSS);
- rlen = cmd_send_and_recv(s, buf, sizeof(buf), resp, sizeof(resp));
- if (rlen < 0)
- return -1;
-
- bssid = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_BSSID, &len);
- if (bssid == NULL)
- return -1;
-
- for (i = 0; i < len / ETH_ALEN; i++)
- printf(MACSTR " ", MAC2STR(bssid + ETH_ALEN * i));
- printf("\n");
-
- return 0;
-}
-
-
-static int cmd_list_sta(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *pos;
- u8 *addr;
- size_t len;
- int rlen, i;
-
- if (argc < 1) {
- printf("list_sta needs one argument: BSSID\n");
- return -1;
- }
-
- pos = buf;
- WPA_PUT_BE32(pos, WLANTEST_CTRL_LIST_STA);
- pos += 4;
- WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
- pos += 4;
- WPA_PUT_BE32(pos, ETH_ALEN);
- pos += 4;
- if (hwaddr_aton(argv[0], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[0]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
-
- addr = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_STA_ADDR, &len);
- if (addr == NULL)
- return -1;
-
- for (i = 0; i < len / ETH_ALEN; i++)
- printf(MACSTR " ", MAC2STR(addr + ETH_ALEN * i));
- printf("\n");
-
- return 0;
-}
-
-
-static char ** complete_list_sta(int s, const char *str, int pos)
-{
- if (get_cmd_arg_num(str, pos) == 1)
- return get_bssid_list(s);
- return NULL;
-}
-
-
-static int cmd_flush(int s, int argc, char *argv[])
-{
- return cmd_simple(s, WLANTEST_CTRL_FLUSH);
-}
-
-
-static int cmd_clear_sta_counters(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *pos;
- int rlen;
-
- if (argc < 2) {
- printf("clear_sta_counters needs two arguments: BSSID and "
- "STA address\n");
- return -1;
- }
-
- pos = buf;
- WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_STA_COUNTERS);
- pos += 4;
- WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
- pos += 4;
- WPA_PUT_BE32(pos, ETH_ALEN);
- pos += 4;
- if (hwaddr_aton(argv[0], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[0]);
- return -1;
- }
- pos += ETH_ALEN;
-
- WPA_PUT_BE32(pos, WLANTEST_ATTR_STA_ADDR);
- pos += 4;
- WPA_PUT_BE32(pos, ETH_ALEN);
- pos += 4;
- if (hwaddr_aton(argv[1], pos) < 0) {
- printf("Invalid STA address '%s'\n", argv[1]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
- printf("OK\n");
- return 0;
-}
-
-
-static char ** complete_clear_sta_counters(int s, const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
- u8 addr[ETH_ALEN];
-
- switch (arg) {
- case 1:
- res = get_bssid_list(s);
- break;
- case 2:
- if (hwaddr_aton(&str[get_prev_arg_pos(str, pos)], addr) < 0)
- break;
- res = get_sta_list(s, addr, 0);
- break;
- }
-
- return res;
-}
-
-
-static int cmd_clear_bss_counters(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *pos;
- int rlen;
-
- if (argc < 1) {
- printf("clear_bss_counters needs one argument: BSSID\n");
- return -1;
- }
-
- pos = buf;
- WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_BSS_COUNTERS);
- pos += 4;
- WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
- pos += 4;
- WPA_PUT_BE32(pos, ETH_ALEN);
- pos += 4;
- if (hwaddr_aton(argv[0], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[0]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
- printf("OK\n");
- return 0;
-}
-
-
-static char ** complete_clear_bss_counters(int s, const char *str, int pos)
-{
- if (get_cmd_arg_num(str, pos) == 1)
- return get_bssid_list(s);
- return NULL;
-}
-
-
-static int cmd_clear_tdls_counters(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *pos;
- int rlen;
-
- if (argc < 3) {
- printf("clear_tdls_counters needs three arguments: BSSID, "
- "STA1 address, STA2 address\n");
- return -1;
- }
-
- pos = buf;
- WPA_PUT_BE32(pos, WLANTEST_CTRL_CLEAR_TDLS_COUNTERS);
- pos += 4;
- WPA_PUT_BE32(pos, WLANTEST_ATTR_BSSID);
- pos += 4;
- WPA_PUT_BE32(pos, ETH_ALEN);
- pos += 4;
- if (hwaddr_aton(argv[0], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[0]);
- return -1;
- }
- pos += ETH_ALEN;
-
- WPA_PUT_BE32(pos, WLANTEST_ATTR_STA_ADDR);
- pos += 4;
- WPA_PUT_BE32(pos, ETH_ALEN);
- pos += 4;
- if (hwaddr_aton(argv[1], pos) < 0) {
- printf("Invalid STA1 address '%s'\n", argv[1]);
- return -1;
- }
- pos += ETH_ALEN;
-
- WPA_PUT_BE32(pos, WLANTEST_ATTR_STA2_ADDR);
- pos += 4;
- WPA_PUT_BE32(pos, ETH_ALEN);
- pos += 4;
- if (hwaddr_aton(argv[2], pos) < 0) {
- printf("Invalid STA2 address '%s'\n", argv[2]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
- printf("OK\n");
- return 0;
-}
-
-
-static char ** complete_clear_tdls_counters(int s, const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
- u8 addr[ETH_ALEN];
-
- switch (arg) {
- case 1:
- res = get_bssid_list(s);
- break;
- case 2:
- case 3:
- if (hwaddr_aton(&str[get_prev_arg_pos(str, pos)], addr) < 0)
- break;
- res = get_sta_list(s, addr, 0);
- break;
- }
-
- return res;
-}
-
-
-struct sta_counters {
- const char *name;
- enum wlantest_sta_counter num;
-};
-
-static const struct sta_counters sta_counters[] = {
- { "auth_tx", WLANTEST_STA_COUNTER_AUTH_TX },
- { "auth_rx", WLANTEST_STA_COUNTER_AUTH_RX },
- { "assocreq_tx", WLANTEST_STA_COUNTER_ASSOCREQ_TX },
- { "reassocreq_tx", WLANTEST_STA_COUNTER_REASSOCREQ_TX },
- { "ptk_learned", WLANTEST_STA_COUNTER_PTK_LEARNED },
- { "valid_deauth_tx", WLANTEST_STA_COUNTER_VALID_DEAUTH_TX },
- { "valid_deauth_rx", WLANTEST_STA_COUNTER_VALID_DEAUTH_RX },
- { "invalid_deauth_tx", WLANTEST_STA_COUNTER_INVALID_DEAUTH_TX },
- { "invalid_deauth_rx", WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX },
- { "valid_disassoc_tx", WLANTEST_STA_COUNTER_VALID_DISASSOC_TX },
- { "valid_disassoc_rx", WLANTEST_STA_COUNTER_VALID_DISASSOC_RX },
- { "invalid_disassoc_tx", WLANTEST_STA_COUNTER_INVALID_DISASSOC_TX },
- { "invalid_disassoc_rx", WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX },
- { "valid_saqueryreq_tx", WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_TX },
- { "valid_saqueryreq_rx", WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_RX },
- { "invalid_saqueryreq_tx",
- WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_TX },
- { "invalid_saqueryreq_rx",
- WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_RX },
- { "valid_saqueryresp_tx", WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_TX },
- { "valid_saqueryresp_rx", WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_RX },
- { "invalid_saqueryresp_tx",
- WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_TX },
- { "invalid_saqueryresp_rx",
- WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX },
- { "ping_ok", WLANTEST_STA_COUNTER_PING_OK },
- { "assocresp_comeback", WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK },
- { "reassocresp_comeback", WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK },
- { "ping_ok_first_assoc", WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC },
- { "valid_deauth_rx_ack", WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK },
- { "valid_disassoc_rx_ack",
- WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK },
- { "invalid_deauth_rx_ack",
- WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK },
- { "invalid_disassoc_rx_ack",
- WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK },
- { "deauth_rx_asleep", WLANTEST_STA_COUNTER_DEAUTH_RX_ASLEEP },
- { "deauth_rx_awake", WLANTEST_STA_COUNTER_DEAUTH_RX_AWAKE },
- { "disassoc_rx_asleep", WLANTEST_STA_COUNTER_DISASSOC_RX_ASLEEP },
- { "disassoc_rx_awake", WLANTEST_STA_COUNTER_DISASSOC_RX_AWAKE },
- { "prot_data_tx", WLANTEST_STA_COUNTER_PROT_DATA_TX },
- { "deauth_rx_rc6", WLANTEST_STA_COUNTER_DEAUTH_RX_RC6 },
- { "deauth_rx_rc7", WLANTEST_STA_COUNTER_DEAUTH_RX_RC7 },
- { "disassoc_rx_rc6", WLANTEST_STA_COUNTER_DISASSOC_RX_RC6 },
- { "disassoc_rx_rc7", WLANTEST_STA_COUNTER_DISASSOC_RX_RC7 },
- { NULL, 0 }
-};
-
-static int cmd_get_sta_counter(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *end, *pos;
- int rlen, i;
- size_t len;
-
- if (argc != 3) {
- printf("get_sta_counter needs at three arguments: "
- "counter name, BSSID, and STA address\n");
- return -1;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_STA_COUNTER);
- pos += 4;
-
- for (i = 0; sta_counters[i].name; i++) {
- if (os_strcasecmp(sta_counters[i].name, argv[0]) == 0)
- break;
- }
- if (sta_counters[i].name == NULL) {
- printf("Unknown STA counter '%s'\n", argv[0]);
- printf("Counters:");
- for (i = 0; sta_counters[i].name; i++)
- printf(" %s", sta_counters[i].name);
- printf("\n");
- return -1;
- }
-
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_STA_COUNTER,
- sta_counters[i].num);
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
- if (hwaddr_aton(argv[1], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[1]);
- return -1;
- }
- pos += ETH_ALEN;
-
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
- if (hwaddr_aton(argv[2], pos) < 0) {
- printf("Invalid STA address '%s'\n", argv[2]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
-
- pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
- if (pos == NULL || len != 4)
- return -1;
- printf("%u\n", WPA_GET_BE32(pos));
- return 0;
-}
-
-
-static char ** complete_get_sta_counter(int s, const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
- int i, count;
- u8 addr[ETH_ALEN];
-
- switch (arg) {
- case 1:
- /* counter list */
- count = sizeof(sta_counters) / sizeof(sta_counters[0]);
- res = os_zalloc(count * sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; sta_counters[i].name; i++) {
- res[i] = os_strdup(sta_counters[i].name);
- if (res[i] == NULL)
- break;
- }
- break;
- case 2:
- res = get_bssid_list(s);
- break;
- case 3:
- if (hwaddr_aton(&str[get_prev_arg_pos(str, pos)], addr) < 0)
- break;
- res = get_sta_list(s, addr, 0);
- break;
- }
-
- return res;
-}
-
-
-struct bss_counters {
- const char *name;
- enum wlantest_bss_counter num;
-};
-
-static const struct bss_counters bss_counters[] = {
- { "valid_bip_mmie", WLANTEST_BSS_COUNTER_VALID_BIP_MMIE },
- { "invalid_bip_mmie", WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE },
- { "missing_bip_mmie", WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE },
- { "bip_deauth", WLANTEST_BSS_COUNTER_BIP_DEAUTH },
- { "bip_disassoc", WLANTEST_BSS_COUNTER_BIP_DISASSOC },
- { NULL, 0 }
-};
-
-static int cmd_get_bss_counter(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *end, *pos;
- int rlen, i;
- size_t len;
-
- if (argc != 2) {
- printf("get_bss_counter needs at two arguments: "
- "counter name and BSSID\n");
- return -1;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_BSS_COUNTER);
- pos += 4;
-
- for (i = 0; bss_counters[i].name; i++) {
- if (os_strcasecmp(bss_counters[i].name, argv[0]) == 0)
- break;
- }
- if (bss_counters[i].name == NULL) {
- printf("Unknown BSS counter '%s'\n", argv[0]);
- printf("Counters:");
- for (i = 0; bss_counters[i].name; i++)
- printf(" %s", bss_counters[i].name);
- printf("\n");
- return -1;
- }
-
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_COUNTER,
- bss_counters[i].num);
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
- if (hwaddr_aton(argv[1], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[1]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
-
- pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
- if (pos == NULL || len != 4)
- return -1;
- printf("%u\n", WPA_GET_BE32(pos));
- return 0;
-}
-
-
-static char ** complete_get_bss_counter(int s, const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
- int i, count;
-
- switch (arg) {
- case 1:
- /* counter list */
- count = sizeof(bss_counters) / sizeof(bss_counters[0]);
- res = os_zalloc(count * sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; bss_counters[i].name; i++) {
- res[i] = os_strdup(bss_counters[i].name);
- if (res[i] == NULL)
- break;
- }
- break;
- case 2:
- res = get_bssid_list(s);
- break;
- }
-
- return res;
-}
-
-
-struct tdls_counters {
- const char *name;
- enum wlantest_tdls_counter num;
-};
-
-static const struct tdls_counters tdls_counters[] = {
- { "valid_direct_link", WLANTEST_TDLS_COUNTER_VALID_DIRECT_LINK },
- { "invalid_direct_link", WLANTEST_TDLS_COUNTER_INVALID_DIRECT_LINK },
- { "valid_ap_path", WLANTEST_TDLS_COUNTER_VALID_AP_PATH },
- { "invalid_ap_path", WLANTEST_TDLS_COUNTER_INVALID_AP_PATH },
- { "setup_req", WLANTEST_TDLS_COUNTER_SETUP_REQ },
- { "setup_resp_ok", WLANTEST_TDLS_COUNTER_SETUP_RESP_OK },
- { "setup_resp_fail", WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL },
- { "setup_conf_ok", WLANTEST_TDLS_COUNTER_SETUP_CONF_OK },
- { "setup_conf_fail", WLANTEST_TDLS_COUNTER_SETUP_CONF_FAIL },
- { "teardown", WLANTEST_TDLS_COUNTER_TEARDOWN },
- { NULL, 0 }
-};
-
-static int cmd_get_tdls_counter(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *end, *pos;
- int rlen, i;
- size_t len;
-
- if (argc != 4) {
- printf("get_tdls_counter needs four arguments: "
- "counter name, BSSID, STA1 address, STA2 address\n");
- return -1;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_GET_TDLS_COUNTER);
- pos += 4;
-
- for (i = 0; tdls_counters[i].name; i++) {
- if (os_strcasecmp(tdls_counters[i].name, argv[0]) == 0)
- break;
- }
- if (tdls_counters[i].name == NULL) {
- printf("Unknown TDLS counter '%s'\n", argv[0]);
- printf("Counters:");
- for (i = 0; tdls_counters[i].name; i++)
- printf(" %s", tdls_counters[i].name);
- printf("\n");
- return -1;
- }
-
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_TDLS_COUNTER,
- tdls_counters[i].num);
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
- if (hwaddr_aton(argv[1], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[1]);
- return -1;
- }
- pos += ETH_ALEN;
-
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
- if (hwaddr_aton(argv[2], pos) < 0) {
- printf("Invalid STA1 address '%s'\n", argv[2]);
- return -1;
- }
- pos += ETH_ALEN;
-
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA2_ADDR, ETH_ALEN);
- if (hwaddr_aton(argv[3], pos) < 0) {
- printf("Invalid STA2 address '%s'\n", argv[3]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
-
- pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_COUNTER, &len);
- if (pos == NULL || len != 4)
- return -1;
- printf("%u\n", WPA_GET_BE32(pos));
- return 0;
-}
-
-
-static char ** complete_get_tdls_counter(int s, const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
- int i, count;
- u8 addr[ETH_ALEN];
-
- switch (arg) {
- case 1:
- /* counter list */
- count = sizeof(tdls_counters) / sizeof(tdls_counters[0]);
- res = os_zalloc(count * sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; tdls_counters[i].name; i++) {
- res[i] = os_strdup(tdls_counters[i].name);
- if (res[i] == NULL)
- break;
- }
- break;
- case 2:
- res = get_bssid_list(s);
- break;
- case 3:
- case 4:
- if (hwaddr_aton(&str[get_prev_arg_pos(str, pos)], addr) < 0)
- break;
- res = get_sta_list(s, addr, 0);
- break;
- }
-
- return res;
-}
-
-
-struct inject_frames {
- const char *name;
- enum wlantest_inject_frame frame;
-};
-
-static const struct inject_frames inject_frames[] = {
- { "auth", WLANTEST_FRAME_AUTH },
- { "assocreq", WLANTEST_FRAME_ASSOCREQ },
- { "reassocreq", WLANTEST_FRAME_REASSOCREQ },
- { "deauth", WLANTEST_FRAME_DEAUTH },
- { "disassoc", WLANTEST_FRAME_DISASSOC },
- { "saqueryreq", WLANTEST_FRAME_SAQUERYREQ },
- { NULL, 0 }
-};
-
-static int cmd_inject(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *end, *pos;
- int rlen, i;
- enum wlantest_inject_protection prot;
-
- /* <frame> <prot> <sender> <BSSID> <STA/ff:ff:ff:ff:ff:ff> */
-
- if (argc < 5) {
- printf("inject needs five arguments: frame, protection, "
- "sender, BSSID, STA/ff:ff:ff:ff:ff:ff\n");
- return -1;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_INJECT);
- pos += 4;
-
- for (i = 0; inject_frames[i].name; i++) {
- if (os_strcasecmp(inject_frames[i].name, argv[0]) == 0)
- break;
- }
- if (inject_frames[i].name == NULL) {
- printf("Unknown inject frame '%s'\n", argv[0]);
- printf("Frames:");
- for (i = 0; inject_frames[i].name; i++)
- printf(" %s", inject_frames[i].name);
- printf("\n");
- return -1;
- }
-
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_FRAME,
- inject_frames[i].frame);
-
- if (os_strcasecmp(argv[1], "normal") == 0)
- prot = WLANTEST_INJECT_NORMAL;
- else if (os_strcasecmp(argv[1], "protected") == 0)
- prot = WLANTEST_INJECT_PROTECTED;
- else if (os_strcasecmp(argv[1], "unprotected") == 0)
- prot = WLANTEST_INJECT_UNPROTECTED;
- else if (os_strcasecmp(argv[1], "incorrect") == 0)
- prot = WLANTEST_INJECT_INCORRECT_KEY;
- else {
- printf("Unknown protection type '%s'\n", argv[1]);
- printf("Protection types: normal protected unprotected "
- "incorrect\n");
- return -1;
- }
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_PROTECTION, prot);
-
- if (os_strcasecmp(argv[2], "ap") == 0) {
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_SENDER_AP,
- 1);
- } else if (os_strcasecmp(argv[2], "sta") == 0) {
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_SENDER_AP,
- 0);
- } else {
- printf("Unknown sender '%s'\n", argv[2]);
- printf("Sender types: ap sta\n");
- return -1;
- }
-
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
- if (hwaddr_aton(argv[3], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[3]);
- return -1;
- }
- pos += ETH_ALEN;
-
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
- if (hwaddr_aton(argv[4], pos) < 0) {
- printf("Invalid STA '%s'\n", argv[4]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
- printf("OK\n");
- return 0;
-}
-
-
-static char ** complete_inject(int s, const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
- int i, count;
- u8 addr[ETH_ALEN];
-
- switch (arg) {
- case 1:
- /* frame list */
- count = sizeof(inject_frames) / sizeof(inject_frames[0]);
- res = os_zalloc(count * sizeof(char *));
- if (res == NULL)
- break;
- for (i = 0; inject_frames[i].name; i++) {
- res[i] = os_strdup(inject_frames[i].name);
- if (res[i] == NULL)
- break;
- }
- break;
- case 2:
- res = os_zalloc(5 * sizeof(char *));
- if (res == NULL)
- break;
- res[0] = os_strdup("normal");
- if (res[0] == NULL)
- break;
- res[1] = os_strdup("protected");
- if (res[1] == NULL)
- break;
- res[2] = os_strdup("unprotected");
- if (res[2] == NULL)
- break;
- res[3] = os_strdup("incorrect");
- if (res[3] == NULL)
- break;
- break;
- case 3:
- res = os_zalloc(3 * sizeof(char *));
- if (res == NULL)
- break;
- res[0] = os_strdup("ap");
- if (res[0] == NULL)
- break;
- res[1] = os_strdup("sta");
- if (res[1] == NULL)
- break;
- break;
- case 4:
- res = get_bssid_list(s);
- break;
- case 5:
- if (hwaddr_aton(&str[get_prev_arg_pos(str, pos)], addr) < 0)
- break;
- res = get_sta_list(s, addr, 1);
- break;
- }
-
- return res;
-}
-
-
-static u8 * add_hex(u8 *pos, u8 *end, const char *str)
-{
- const char *s;
- int val;
-
- s = str;
- while (*s) {
- while (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n' ||
- *s == ':')
- s++;
- if (*s == '\0')
- break;
- if (*s == '#') {
- while (*s != '\0' && *s != '\r' && *s != '\n')
- s++;
- continue;
- }
-
- val = hex2byte(s);
- if (val < 0) {
- printf("Invalid hex encoding '%s'\n", s);
- return NULL;
- }
- if (pos == end) {
- printf("Too long frame\n");
- return NULL;
- }
- *pos++ = val;
- s += 2;
- }
-
- return pos;
-}
-
-
-static int cmd_send(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[WLANTEST_CTRL_MAX_CMD_LEN], *end, *pos, *len_pos;
- int rlen;
- enum wlantest_inject_protection prot;
- int arg;
-
- /* <prot> <raw frame as hex dump> */
-
- if (argc < 2) {
- printf("send needs two arguments: protected/unprotected, "
- "raw frame as hex dump\n");
- return -1;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_SEND);
- pos += 4;
-
- if (os_strcasecmp(argv[0], "normal") == 0)
- prot = WLANTEST_INJECT_NORMAL;
- else if (os_strcasecmp(argv[0], "protected") == 0)
- prot = WLANTEST_INJECT_PROTECTED;
- else if (os_strcasecmp(argv[0], "unprotected") == 0)
- prot = WLANTEST_INJECT_UNPROTECTED;
- else if (os_strcasecmp(argv[0], "incorrect") == 0)
- prot = WLANTEST_INJECT_INCORRECT_KEY;
- else {
- printf("Unknown protection type '%s'\n", argv[1]);
- printf("Protection types: normal protected unprotected "
- "incorrect\n");
- return -1;
- }
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_INJECT_PROTECTION, prot);
-
- WPA_PUT_BE32(pos, WLANTEST_ATTR_FRAME);
- pos += 4;
- len_pos = pos;
- pos += 4;
-
- for (arg = 1; pos && arg < argc; arg++)
- pos = add_hex(pos, end, argv[arg]);
- if (pos == NULL)
- return -1;
-
- WPA_PUT_BE32(len_pos, pos - len_pos - 4);
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
- printf("OK\n");
- return 0;
-}
-
-
-static char ** complete_send(int s, const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
-
- switch (arg) {
- case 1:
- res = os_zalloc(5 * sizeof(char *));
- if (res == NULL)
- break;
- res[0] = os_strdup("normal");
- if (res[0] == NULL)
- break;
- res[1] = os_strdup("protected");
- if (res[1] == NULL)
- break;
- res[2] = os_strdup("unprotected");
- if (res[2] == NULL)
- break;
- res[3] = os_strdup("incorrect");
- if (res[3] == NULL)
- break;
- break;
- }
-
- return res;
-}
-
-
-static int cmd_version(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[4];
- char *version;
- size_t len;
- int rlen, i;
-
- WPA_PUT_BE32(buf, WLANTEST_CTRL_VERSION);
- rlen = cmd_send_and_recv(s, buf, sizeof(buf), resp, sizeof(resp));
- if (rlen < 0)
- return -1;
-
- version = (char *) attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_VERSION,
- &len);
- if (version == NULL)
- return -1;
-
- for (i = 0; i < len; i++)
- putchar(version[i]);
- printf("\n");
-
- return 0;
-}
-
-
-static int cmd_add_passphrase(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *pos, *end;
- size_t len;
- int rlen;
-
- if (argc < 1) {
- printf("add_passphrase needs one argument: passphrase\n");
- return -1;
- }
-
- len = os_strlen(argv[0]);
- if (len < 8 || len > 63) {
- printf("Invalid passphrase '%s'\n", argv[0]);
- return -1;
- }
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_ADD_PASSPHRASE);
- pos += 4;
- pos = attr_add_str(pos, end, WLANTEST_ATTR_PASSPHRASE,
- argv[0]);
- if (argc > 1) {
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
- if (hwaddr_aton(argv[1], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[3]);
- return -1;
- }
- pos += ETH_ALEN;
- }
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
- return 0;
-}
-
-
-struct sta_infos {
- const char *name;
- enum wlantest_sta_info num;
-};
-
-static const struct sta_infos sta_infos[] = {
- { "proto", WLANTEST_STA_INFO_PROTO },
- { "pairwise", WLANTEST_STA_INFO_PAIRWISE },
- { "key_mgmt", WLANTEST_STA_INFO_KEY_MGMT },
- { "rsn_capab", WLANTEST_STA_INFO_RSN_CAPAB },
- { "state", WLANTEST_STA_INFO_STATE },
- { "gtk", WLANTEST_STA_INFO_GTK },
- { NULL, 0 }
-};
-
-static int cmd_info_sta(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *end, *pos;
- int rlen, i;
- size_t len;
- char info[100];
-
- if (argc != 3) {
- printf("sta_info needs at three arguments: "
- "counter name, BSSID, and STA address\n");
- return -1;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_INFO_STA);
- pos += 4;
-
- for (i = 0; sta_infos[i].name; i++) {
- if (os_strcasecmp(sta_infos[i].name, argv[0]) == 0)
- break;
- }
- if (sta_infos[i].name == NULL) {
- printf("Unknown STA info '%s'\n", argv[0]);
- printf("Info fields:");
- for (i = 0; sta_infos[i].name; i++)
- printf(" %s", sta_infos[i].name);
- printf("\n");
- return -1;
- }
-
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_STA_INFO,
- sta_infos[i].num);
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
- if (hwaddr_aton(argv[1], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[1]);
- return -1;
- }
- pos += ETH_ALEN;
-
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_STA_ADDR, ETH_ALEN);
- if (hwaddr_aton(argv[2], pos) < 0) {
- printf("Invalid STA address '%s'\n", argv[2]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
-
- pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_INFO, &len);
- if (pos == NULL)
- return -1;
- if (len >= sizeof(info))
- len = sizeof(info) - 1;
- os_memcpy(info, pos, len);
- info[len] = '\0';
- printf("%s\n", info);
- return 0;
-}
-
-
-static char ** complete_info_sta(int s, const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
- int i, count;
- u8 addr[ETH_ALEN];
-
- switch (arg) {
- case 1:
- /* counter list */
- count = sizeof(sta_infos) / sizeof(sta_infos[0]);
- res = os_zalloc(count * sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; sta_infos[i].name; i++) {
- res[i] = os_strdup(sta_infos[i].name);
- if (res[i] == NULL)
- break;
- }
- break;
- case 2:
- res = get_bssid_list(s);
- break;
- case 3:
- if (hwaddr_aton(&str[get_prev_arg_pos(str, pos)], addr) < 0)
- break;
- res = get_sta_list(s, addr, 0);
- break;
- }
-
- return res;
-}
-
-
-struct bss_infos {
- const char *name;
- enum wlantest_bss_info num;
-};
-
-static const struct bss_infos bss_infos[] = {
- { "proto", WLANTEST_BSS_INFO_PROTO },
- { "pairwise", WLANTEST_BSS_INFO_PAIRWISE },
- { "group", WLANTEST_BSS_INFO_GROUP },
- { "group_mgmt", WLANTEST_BSS_INFO_GROUP_MGMT },
- { "key_mgmt", WLANTEST_BSS_INFO_KEY_MGMT },
- { "rsn_capab", WLANTEST_BSS_INFO_RSN_CAPAB },
- { NULL, 0 }
-};
-
-static int cmd_info_bss(int s, int argc, char *argv[])
-{
- u8 resp[WLANTEST_CTRL_MAX_RESP_LEN];
- u8 buf[100], *end, *pos;
- int rlen, i;
- size_t len;
- char info[100];
-
- if (argc != 2) {
- printf("bss_info needs at two arguments: "
- "field name and BSSID\n");
- return -1;
- }
-
- pos = buf;
- end = buf + sizeof(buf);
- WPA_PUT_BE32(pos, WLANTEST_CTRL_INFO_BSS);
- pos += 4;
-
- for (i = 0; bss_infos[i].name; i++) {
- if (os_strcasecmp(bss_infos[i].name, argv[0]) == 0)
- break;
- }
- if (bss_infos[i].name == NULL) {
- printf("Unknown BSS info '%s'\n", argv[0]);
- printf("Info fields:");
- for (i = 0; bss_infos[i].name; i++)
- printf(" %s", bss_infos[i].name);
- printf("\n");
- return -1;
- }
-
- pos = attr_add_be32(pos, end, WLANTEST_ATTR_BSS_INFO,
- bss_infos[i].num);
- pos = attr_hdr_add(pos, end, WLANTEST_ATTR_BSSID, ETH_ALEN);
- if (hwaddr_aton(argv[1], pos) < 0) {
- printf("Invalid BSSID '%s'\n", argv[1]);
- return -1;
- }
- pos += ETH_ALEN;
-
- rlen = cmd_send_and_recv(s, buf, pos - buf, resp, sizeof(resp));
- if (rlen < 0)
- return -1;
-
- pos = attr_get(resp + 4, rlen - 4, WLANTEST_ATTR_INFO, &len);
- if (pos == NULL)
- return -1;
- if (len >= sizeof(info))
- len = sizeof(info) - 1;
- os_memcpy(info, pos, len);
- info[len] = '\0';
- printf("%s\n", info);
- return 0;
-}
-
-
-static char ** complete_info_bss(int s, const char *str, int pos)
-{
- int arg = get_cmd_arg_num(str, pos);
- char **res = NULL;
- int i, count;
-
- switch (arg) {
- case 1:
- /* counter list */
- count = sizeof(bss_infos) / sizeof(bss_infos[0]);
- res = os_zalloc(count * sizeof(char *));
- if (res == NULL)
- return NULL;
- for (i = 0; bss_infos[i].name; i++) {
- res[i] = os_strdup(bss_infos[i].name);
- if (res[i] == NULL)
- break;
- }
- break;
- case 2:
- res = get_bssid_list(s);
- break;
- }
-
- return res;
-}
-
-
-struct wlantest_cli_cmd {
- const char *cmd;
- int (*handler)(int s, int argc, char *argv[]);
- const char *usage;
- char ** (*complete)(int s, const char *str, int pos);
-};
-
-static const struct wlantest_cli_cmd wlantest_cli_commands[] = {
- { "ping", cmd_ping, "= test connection to wlantest", NULL },
- { "terminate", cmd_terminate, "= terminate wlantest", NULL },
- { "list_bss", cmd_list_bss, "= get BSS list", NULL },
- { "list_sta", cmd_list_sta, "<BSSID> = get STA list",
- complete_list_sta },
- { "flush", cmd_flush, "= drop all collected BSS data", NULL },
- { "clear_sta_counters", cmd_clear_sta_counters,
- "<BSSID> <STA> = clear STA counters", complete_clear_sta_counters },
- { "clear_bss_counters", cmd_clear_bss_counters,
- "<BSSID> = clear BSS counters", complete_clear_bss_counters },
- { "get_sta_counter", cmd_get_sta_counter,
- "<counter> <BSSID> <STA> = get STA counter value",
- complete_get_sta_counter },
- { "get_bss_counter", cmd_get_bss_counter,
- "<counter> <BSSID> = get BSS counter value",
- complete_get_bss_counter },
- { "inject", cmd_inject,
- "<frame> <prot> <sender> <BSSID> <STA/ff:ff:ff:ff:ff:ff>",
- complete_inject },
- { "send", cmd_send,
- "<prot> <raw frame as hex dump>",
- complete_send },
- { "version", cmd_version, "= get wlantest version", NULL },
- { "add_passphrase", cmd_add_passphrase,
- "<passphrase> = add a known passphrase", NULL },
- { "info_sta", cmd_info_sta,
- "<field> <BSSID> <STA> = get STA information",
- complete_info_sta },
- { "info_bss", cmd_info_bss,
- "<field> <BSSID> = get BSS information",
- complete_info_bss },
- { "clear_tdls_counters", cmd_clear_tdls_counters,
- "<BSSID> <STA1> <STA2> = clear TDLS counters",
- complete_clear_tdls_counters },
- { "get_tdls_counter", cmd_get_tdls_counter,
- "<counter> <BSSID> <STA1> <STA2> = get TDLS counter value",
- complete_get_tdls_counter },
- { "get_bss_counter", cmd_get_bss_counter,
- "<counter> <BSSID> = get BSS counter value",
- complete_get_bss_counter },
- { NULL, NULL, NULL, NULL }
-};
-
-
-static int ctrl_command(int s, int argc, char *argv[])
-{
- const struct wlantest_cli_cmd *cmd, *match = NULL;
- int count = 0;
- int ret = 0;
-
- for (cmd = wlantest_cli_commands; cmd->cmd; cmd++) {
- if (os_strncasecmp(cmd->cmd, argv[0], os_strlen(argv[0])) == 0)
- {
- match = cmd;
- if (os_strcasecmp(cmd->cmd, argv[0]) == 0) {
- /* exact match */
- count = 1;
- break;
- }
- count++;
- }
- }
-
- if (count > 1) {
- printf("Ambiguous command '%s'; possible commands:", argv[0]);
- for (cmd = wlantest_cli_commands; cmd->cmd; cmd++) {
- if (os_strncasecmp(cmd->cmd, argv[0],
- os_strlen(argv[0])) == 0) {
- printf(" %s", cmd->cmd);
- }
- }
- printf("\n");
- ret = 1;
- } else if (count == 0) {
- printf("Unknown command '%s'\n", argv[0]);
- ret = 1;
- } else {
- ret = match->handler(s, argc - 1, &argv[1]);
- }
-
- return ret;
-}
-
-
-struct wlantest_cli {
- int s;
-};
-
-
-#define max_args 10
-
-static int tokenize_cmd(char *cmd, char *argv[])
-{
- char *pos;
- int argc = 0;
-
- pos = cmd;
- for (;;) {
- while (*pos == ' ')
- pos++;
- if (*pos == '\0')
- break;
- argv[argc] = pos;
- argc++;
- if (argc == max_args)
- break;
- if (*pos == '"') {
- char *pos2 = os_strrchr(pos, '"');
- if (pos2)
- pos = pos2 + 1;
- }
- while (*pos != '\0' && *pos != ' ')
- pos++;
- if (*pos == ' ')
- *pos++ = '\0';
- }
-
- return argc;
-}
-
-
-static void wlantest_cli_edit_cmd_cb(void *ctx, char *cmd)
-{
- struct wlantest_cli *cli = ctx;
- char *argv[max_args];
- int argc;
- argc = tokenize_cmd(cmd, argv);
- if (argc) {
- int ret = ctrl_command(cli->s, argc, argv);
- if (ret < 0)
- printf("FAIL\n");
- }
-}
-
-
-static void wlantest_cli_eloop_terminate(int sig, void *signal_ctx)
-{
- eloop_terminate();
-}
-
-
-static void wlantest_cli_edit_eof_cb(void *ctx)
-{
- eloop_terminate();
-}
-
-
-static char ** wlantest_cli_cmd_list(void)
-{
- char **res;
- int i, count;
-
- count = sizeof(wlantest_cli_commands) /
- sizeof(wlantest_cli_commands[0]);
- res = os_zalloc(count * sizeof(char *));
- if (res == NULL)
- return NULL;
-
- for (i = 0; wlantest_cli_commands[i].cmd; i++) {
- res[i] = os_strdup(wlantest_cli_commands[i].cmd);
- if (res[i] == NULL)
- break;
- }
-
- return res;
-}
-
-
-static char ** wlantest_cli_cmd_completion(struct wlantest_cli *cli,
- const char *cmd, const char *str,
- int pos)
-{
- int i;
-
- for (i = 0; wlantest_cli_commands[i].cmd; i++) {
- const struct wlantest_cli_cmd *c = &wlantest_cli_commands[i];
- if (os_strcasecmp(c->cmd, cmd) == 0) {
- edit_clear_line();
- printf("\r%s\n", c->usage);
- edit_redraw();
- if (c->complete)
- return c->complete(cli->s, str, pos);
- break;
- }
- }
-
- return NULL;
-}
-
-
-static char ** wlantest_cli_edit_completion_cb(void *ctx, const char *str,
- int pos)
-{
- struct wlantest_cli *cli = ctx;
- char **res;
- const char *end;
- char *cmd;
-
- end = os_strchr(str, ' ');
- if (end == NULL || str + pos < end)
- return wlantest_cli_cmd_list();
-
- cmd = os_malloc(pos + 1);
- if (cmd == NULL)
- return NULL;
- os_memcpy(cmd, str, pos);
- cmd[end - str] = '\0';
- res = wlantest_cli_cmd_completion(cli, cmd, str, pos);
- os_free(cmd);
- return res;
-}
-
-
-static void wlantest_cli_interactive(int s)
-{
- struct wlantest_cli cli;
- char *home, *hfile = NULL;
-
- if (eloop_init())
- return;
-
- home = getenv("HOME");
- if (home) {
- const char *fname = ".wlantest_cli_history";
- int hfile_len = os_strlen(home) + 1 + os_strlen(fname) + 1;
- hfile = os_malloc(hfile_len);
- if (hfile)
- os_snprintf(hfile, hfile_len, "%s/%s", home, fname);
- }
-
- cli.s = s;
- eloop_register_signal_terminate(wlantest_cli_eloop_terminate, &cli);
- edit_init(wlantest_cli_edit_cmd_cb, wlantest_cli_edit_eof_cb,
- wlantest_cli_edit_completion_cb, &cli, hfile);
-
- eloop_run();
-
- edit_deinit(hfile, NULL);
- os_free(hfile);
- eloop_destroy();
-}
-
-
-int main(int argc, char *argv[])
-{
- int s;
- struct sockaddr_un addr;
- int ret = 0;
-
- if (os_program_init())
- return -1;
-
- s = socket(AF_UNIX, SOCK_SEQPACKET, 0);
- if (s < 0) {
- perror("socket");
- return -1;
- }
-
- os_memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- os_strlcpy(addr.sun_path + 1, WLANTEST_SOCK_NAME,
- sizeof(addr.sun_path) - 1);
- if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
- perror("connect");
- close(s);
- return -1;
- }
-
- if (argc > 1) {
- ret = ctrl_command(s, argc - 1, &argv[1]);
- if (ret < 0)
- printf("FAIL\n");
- } else {
- wlantest_cli_interactive(s);
- }
-
- close(s);
-
- os_program_deinit();
-
- return ret;
-}
diff --git a/wlantest/wlantest_ctrl.h b/wlantest/wlantest_ctrl.h
deleted file mode 100644
index 618cf8c..0000000
--- a/wlantest/wlantest_ctrl.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * wlantest control interface
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WLANTEST_CTRL_H
-#define WLANTEST_CTRL_H
-
-#define WLANTEST_SOCK_NAME "w1.fi.wlantest"
-#define WLANTEST_CTRL_MAX_CMD_LEN 1000
-#define WLANTEST_CTRL_MAX_RESP_LEN 1000
-
-enum wlantest_ctrl_cmd {
- WLANTEST_CTRL_SUCCESS,
- WLANTEST_CTRL_FAILURE,
- WLANTEST_CTRL_INVALID_CMD,
- WLANTEST_CTRL_UNKNOWN_CMD,
- WLANTEST_CTRL_PING,
- WLANTEST_CTRL_TERMINATE,
- WLANTEST_CTRL_LIST_BSS,
- WLANTEST_CTRL_LIST_STA,
- WLANTEST_CTRL_FLUSH,
- WLANTEST_CTRL_CLEAR_STA_COUNTERS,
- WLANTEST_CTRL_CLEAR_BSS_COUNTERS,
- WLANTEST_CTRL_GET_STA_COUNTER,
- WLANTEST_CTRL_GET_BSS_COUNTER,
- WLANTEST_CTRL_INJECT,
- WLANTEST_CTRL_VERSION,
- WLANTEST_CTRL_ADD_PASSPHRASE,
- WLANTEST_CTRL_INFO_STA,
- WLANTEST_CTRL_INFO_BSS,
- WLANTEST_CTRL_SEND,
- WLANTEST_CTRL_CLEAR_TDLS_COUNTERS,
- WLANTEST_CTRL_GET_TDLS_COUNTER,
-};
-
-enum wlantest_ctrl_attr {
- WLANTEST_ATTR_BSSID,
- WLANTEST_ATTR_STA_ADDR,
- WLANTEST_ATTR_STA_COUNTER,
- WLANTEST_ATTR_BSS_COUNTER,
- WLANTEST_ATTR_COUNTER,
- WLANTEST_ATTR_INJECT_FRAME,
- WLANTEST_ATTR_INJECT_SENDER_AP,
- WLANTEST_ATTR_INJECT_PROTECTION,
- WLANTEST_ATTR_VERSION,
- WLANTEST_ATTR_PASSPHRASE,
- WLANTEST_ATTR_STA_INFO,
- WLANTEST_ATTR_BSS_INFO,
- WLANTEST_ATTR_INFO,
- WLANTEST_ATTR_FRAME,
- WLANTEST_ATTR_TDLS_COUNTER,
- WLANTEST_ATTR_STA2_ADDR,
- WLANTEST_ATTR_WEPKEY,
-};
-
-enum wlantest_bss_counter {
- WLANTEST_BSS_COUNTER_VALID_BIP_MMIE,
- WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE,
- WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE,
- WLANTEST_BSS_COUNTER_BIP_DEAUTH,
- WLANTEST_BSS_COUNTER_BIP_DISASSOC,
- NUM_WLANTEST_BSS_COUNTER
-};
-
-enum wlantest_sta_counter {
- WLANTEST_STA_COUNTER_AUTH_TX,
- WLANTEST_STA_COUNTER_AUTH_RX,
- WLANTEST_STA_COUNTER_ASSOCREQ_TX,
- WLANTEST_STA_COUNTER_REASSOCREQ_TX,
- WLANTEST_STA_COUNTER_PTK_LEARNED,
- WLANTEST_STA_COUNTER_VALID_DEAUTH_TX,
- WLANTEST_STA_COUNTER_VALID_DEAUTH_RX,
- WLANTEST_STA_COUNTER_INVALID_DEAUTH_TX,
- WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX,
- WLANTEST_STA_COUNTER_VALID_DISASSOC_TX,
- WLANTEST_STA_COUNTER_VALID_DISASSOC_RX,
- WLANTEST_STA_COUNTER_INVALID_DISASSOC_TX,
- WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX,
- WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_TX,
- WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_RX,
- WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_TX,
- WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_RX,
- WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_TX,
- WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_RX,
- WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_TX,
- WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX,
- WLANTEST_STA_COUNTER_PING_OK,
- WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK,
- WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK,
- WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC,
- WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK,
- WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK,
- WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK,
- WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK,
- WLANTEST_STA_COUNTER_DEAUTH_RX_ASLEEP,
- WLANTEST_STA_COUNTER_DEAUTH_RX_AWAKE,
- WLANTEST_STA_COUNTER_DISASSOC_RX_ASLEEP,
- WLANTEST_STA_COUNTER_DISASSOC_RX_AWAKE,
- WLANTEST_STA_COUNTER_PROT_DATA_TX,
- WLANTEST_STA_COUNTER_DEAUTH_RX_RC6,
- WLANTEST_STA_COUNTER_DEAUTH_RX_RC7,
- WLANTEST_STA_COUNTER_DISASSOC_RX_RC6,
- WLANTEST_STA_COUNTER_DISASSOC_RX_RC7,
- NUM_WLANTEST_STA_COUNTER
-};
-
-enum wlantest_tdls_counter {
- WLANTEST_TDLS_COUNTER_VALID_DIRECT_LINK,
- WLANTEST_TDLS_COUNTER_INVALID_DIRECT_LINK,
- WLANTEST_TDLS_COUNTER_VALID_AP_PATH,
- WLANTEST_TDLS_COUNTER_INVALID_AP_PATH,
- WLANTEST_TDLS_COUNTER_SETUP_REQ,
- WLANTEST_TDLS_COUNTER_SETUP_RESP_OK,
- WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL,
- WLANTEST_TDLS_COUNTER_SETUP_CONF_OK,
- WLANTEST_TDLS_COUNTER_SETUP_CONF_FAIL,
- WLANTEST_TDLS_COUNTER_TEARDOWN,
- NUM_WLANTEST_TDLS_COUNTER
-};
-
-enum wlantest_inject_frame {
- WLANTEST_FRAME_AUTH,
- WLANTEST_FRAME_ASSOCREQ,
- WLANTEST_FRAME_REASSOCREQ,
- WLANTEST_FRAME_DEAUTH,
- WLANTEST_FRAME_DISASSOC,
- WLANTEST_FRAME_SAQUERYREQ,
-};
-
-/**
- * enum wlantest_inject_protection - WLANTEST_CTRL_INJECT protection
- * @WLANTEST_INJECT_NORMAL: Use normal rules (protect if key is set)
- * @WLANTEST_INJECT_PROTECTED: Force protection (fail if not possible)
- * @WLANTEST_INJECT_UNPROTECTED: Force unprotected
- * @WLANTEST_INJECT_INCORRECT_KEY: Force protection with incorrect key
- */
-enum wlantest_inject_protection {
- WLANTEST_INJECT_NORMAL,
- WLANTEST_INJECT_PROTECTED,
- WLANTEST_INJECT_UNPROTECTED,
- WLANTEST_INJECT_INCORRECT_KEY,
-};
-
-enum wlantest_sta_info {
- WLANTEST_STA_INFO_PROTO,
- WLANTEST_STA_INFO_PAIRWISE,
- WLANTEST_STA_INFO_KEY_MGMT,
- WLANTEST_STA_INFO_RSN_CAPAB,
- WLANTEST_STA_INFO_STATE,
- WLANTEST_STA_INFO_GTK,
-};
-
-enum wlantest_bss_info {
- WLANTEST_BSS_INFO_PROTO,
- WLANTEST_BSS_INFO_PAIRWISE,
- WLANTEST_BSS_INFO_GROUP,
- WLANTEST_BSS_INFO_GROUP_MGMT,
- WLANTEST_BSS_INFO_KEY_MGMT,
- WLANTEST_BSS_INFO_RSN_CAPAB,
-};
-
-#endif /* WLANTEST_CTRL_H */
diff --git a/wlantest/writepcap.c b/wlantest/writepcap.c
deleted file mode 100644
index dac0597..0000000
--- a/wlantest/writepcap.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * PCAP capture file writer
- * Copyright (c) 2010, Jouni Malinen <j@w1.fi>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "utils/includes.h"
-#include <pcap.h>
-#include <pcap-bpf.h>
-
-#include "utils/common.h"
-#include "wlantest.h"
-
-
-int write_pcap_init(struct wlantest *wt, const char *fname)
-{
- wt->write_pcap = pcap_open_dead(DLT_IEEE802_11_RADIO, 4000);
- if (wt->write_pcap == NULL)
- return -1;
- wt->write_pcap_dumper = pcap_dump_open(wt->write_pcap, fname);
- if (wt->write_pcap_dumper == NULL) {
- pcap_close(wt->write_pcap);
- wt->write_pcap = NULL;
- return -1;
- }
-
- wpa_printf(MSG_DEBUG, "Writing PCAP dump to '%s'", fname);
-
- return 0;
-}
-
-
-void write_pcap_deinit(struct wlantest *wt)
-{
- if (wt->write_pcap_dumper) {
- pcap_dump_close(wt->write_pcap_dumper);
- wt->write_pcap_dumper = NULL;
- }
- if (wt->write_pcap) {
- pcap_close(wt->write_pcap);
- wt->write_pcap = NULL;
- }
-}
-
-
-void write_pcap_captured(struct wlantest *wt, const u8 *buf, size_t len)
-{
- struct pcap_pkthdr h;
-
- if (!wt->write_pcap_dumper)
- return;
-
- os_memset(&h, 0, sizeof(h));
- gettimeofday(&wt->write_pcap_time, NULL);
- h.ts = wt->write_pcap_time;
- h.caplen = len;
- h.len = len;
- pcap_dump(wt->write_pcap_dumper, &h, buf);
-}
-
-
-void write_pcap_decrypted(struct wlantest *wt, const u8 *buf1, size_t len1,
- const u8 *buf2, size_t len2)
-{
- struct pcap_pkthdr h;
- u8 rtap[] = {
- 0x00 /* rev */,
- 0x00 /* pad */,
- 0x08, 0x00, /* header len */
- 0x00, 0x00, 0x00, 0x00 /* present flags */
- };
- u8 *buf;
- size_t len;
-
- if (!wt->write_pcap_dumper)
- return;
-
- os_memset(&h, 0, sizeof(h));
- h.ts = wt->write_pcap_time;
- len = sizeof(rtap) + len1 + len2;
- buf = os_malloc(len);
- if (buf == NULL)
- return;
- os_memcpy(buf, rtap, sizeof(rtap));
- if (buf1) {
- os_memcpy(buf + sizeof(rtap), buf1, len1);
- buf[sizeof(rtap) + 1] &= ~0x40; /* Clear Protected flag */
- }
- if (buf2)
- os_memcpy(buf + sizeof(rtap) + len1, buf2, len2);
- h.caplen = len;
- h.len = len;
- pcap_dump(wt->write_pcap_dumper, &h, buf);
- os_free(buf);
-}