summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 8f15f71)
raw | patch | inline | side by side (parent: 8f15f71)
author | Arik Nemtsov <arik@wizery.com> | |
Mon, 26 Sep 2011 10:55:31 +0000 (13:55 +0300) | ||
committer | Jouni Malinen <j@w1.fi> | |
Sun, 23 Oct 2011 19:19:13 +0000 (22:19 +0300) |
Record the capabilities and supported rates of the TDLS peer during
link setup. These are given in the IEs passed in Setup Request and
Setup Response frames.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Cc: Kalyan C Gaddam <chakkal@iit.edu>
link setup. These are given in the IEs passed in Setup Request and
Setup Response frames.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Cc: Kalyan C Gaddam <chakkal@iit.edu>
src/rsn_supp/tdls.c | patch | blob | history | |
src/rsn_supp/wpa_ie.c | patch | blob | history | |
src/rsn_supp/wpa_ie.h | patch | blob | history |
diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c
index 9fe247c2750b6318a2e68f303f437e2d0724efc4..45db2b346bce75ec29d311034ecd9cd4a945c705 100644 (file)
--- a/src/rsn_supp/tdls.c
+++ b/src/rsn_supp/tdls.c
#define TDLS_MAX_IE_LEN 80
+#define IEEE80211_MAX_SUPP_RATES 32
+
struct wpa_tdls_peer {
struct wpa_tdls_peer *next;
int initiator; /* whether this end was initiator for TDLS setup */
int buf_len; /* length of TPK message for retransmission */
u8 *buf; /* buffer for TPK message */
} sm_tmr;
+
+ u16 capability;
+
+ u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
+ size_t supp_rates_len;
};
}
+static int copy_supp_rates(const struct wpa_eapol_ie_parse *kde,
+ struct wpa_tdls_peer *peer)
+{
+ if (!kde->supp_rates) {
+ wpa_printf(MSG_DEBUG, "TDLS: No supported rates received");
+ return -1;
+ }
+
+ peer->supp_rates_len = kde->supp_rates_len - 2;
+ if (peer->supp_rates_len > IEEE80211_MAX_SUPP_RATES)
+ peer->supp_rates_len = IEEE80211_MAX_SUPP_RATES;
+ os_memcpy(peer->supp_rates, kde->supp_rates + 2, peer->supp_rates_len);
+
+ if (kde->ext_supp_rates) {
+ int clen = kde->ext_supp_rates_len - 2;
+ if (peer->supp_rates_len + clen > IEEE80211_MAX_SUPP_RATES)
+ clen = IEEE80211_MAX_SUPP_RATES - peer->supp_rates_len;
+ os_memcpy(peer->supp_rates + peer->supp_rates_len,
+ kde->ext_supp_rates + 2, clen);
+ peer->supp_rates_len += clen;
+ }
+
+ return 0;
+}
+
+
static int wpa_tdls_process_tpk_m1(struct wpa_sm *sm, const u8 *src_addr,
const u8 *buf, size_t len)
{
u16 ielen;
u16 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
int tdls_prohibited = sm->tdls_prohibited;
+ int existing_peer = 0;
if (len < 3 + 3)
return -1;
wpa_printf(MSG_INFO, "TDLS: Dialog Token in TPK M1 %d", dtoken);
- cpos += 2; /* capability information */
+ for (peer = sm->tdls; peer; peer = peer->next) {
+ if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0) {
+ existing_peer = 1;
+ break;
+ }
+ }
+
+ if (peer == NULL) {
+ peer = wpa_tdls_add_peer(sm, src_addr);
+ if (peer == NULL)
+ goto error;
+ }
+
+ /* capability information */
+ peer->capability = WPA_GET_LE16(cpos);
+ cpos += 2;
ielen = len - (cpos - buf); /* start of IE in buf */
if (wpa_supplicant_parse_ies(cpos, ielen, &kde) < 0) {
wpa_printf(MSG_DEBUG, "TDLS: TPK M1 - TPK initiator " MACSTR,
MAC2STR(src_addr));
+ if (copy_supp_rates(&kde, peer) < 0)
+ goto error;
+
#ifdef CONFIG_TDLS_TESTING
if (tdls_testing & TDLS_TESTING_CONCURRENT_INIT) {
for (peer = sm->tdls; peer; peer = peer->next) {
}
skip_rsn:
- /* Find existing entry and if found, use that instead of adding
- * a new one; how to handle the case where both ends initiate at the
+ /* If found, use existing entry instead of adding a new one;
+ * how to handle the case where both ends initiate at the
* same time? */
- for (peer = sm->tdls; peer; peer = peer->next) {
- if (os_memcmp(peer->addr, src_addr, ETH_ALEN) == 0)
- break;
- }
-
- if (peer == NULL) {
- wpa_printf(MSG_INFO, "TDLS: No matching entry found for "
- "peer, creating one for " MACSTR,
- MAC2STR(src_addr));
- peer = os_malloc(sizeof(*peer));
- if (peer == NULL)
- goto error;
- os_memset(peer, 0, sizeof(*peer));
- os_memcpy(peer->addr, src_addr, ETH_ALEN);
- peer->next = sm->tdls;
- sm->tdls = peer;
- } else {
+ if (existing_peer) {
if (peer->tpk_success) {
wpa_printf(MSG_DEBUG, "TDLS: TDLS Setup Request while "
"direct link is enabled - tear down the "
if (len < 3 + 2 + 1 + 2)
return -1;
- pos += 2; /* capability information */
+
+ /* capability information */
+ peer->capability = WPA_GET_LE16(pos);
+ pos += 2;
ielen = len - (pos - buf); /* start of IE in buf */
if (wpa_supplicant_parse_ies(pos, ielen, &kde) < 0) {
goto error;
}
+ if (copy_supp_rates(&kde, peer) < 0)
+ goto error;
+
if (!wpa_tdls_get_privacy(sm)) {
peer->rsnie_p_len = 0;
peer->cipher = WPA_CIPHER_NONE;
diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c
index 654cc1f1534096755265694c59d7097ff1476957..cbbc54fd6ab1854265c98b6e7e16e7743eaec4f9 100644 (file)
--- a/src/rsn_supp/wpa_ie.c
+++ b/src/rsn_supp/wpa_ie.c
pos, 2 + pos[1]);
}
} else if (*pos == WLAN_EID_LINK_ID) {
- ie->lnkid = pos;
- ie->lnkid_len = pos[1] + 2;
+ if (pos[1] >= 18) {
+ ie->lnkid = pos;
+ ie->lnkid_len = pos[1] + 2;
+ }
} else if (*pos == WLAN_EID_EXT_CAPAB) {
ie->ext_capab = pos;
ie->ext_capab_len = pos[1] + 2;
+ } else if (*pos == WLAN_EID_SUPP_RATES) {
+ ie->supp_rates = pos;
+ ie->supp_rates_len = pos[1] + 2;
+ } else if (*pos == WLAN_EID_EXT_SUPP_RATES) {
+ ie->ext_supp_rates = pos;
+ ie->ext_supp_rates_len = pos[1] + 2;
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
ret = wpa_parse_generic(pos, end, ie);
if (ret < 0)
diff --git a/src/rsn_supp/wpa_ie.h b/src/rsn_supp/wpa_ie.h
index f939b13d1e7437d4588dfe6d374c9e4060a69b93..c13d94c6a55e2e37bccac3bb9584d6c9938e0424 100644 (file)
--- a/src/rsn_supp/wpa_ie.h
+++ b/src/rsn_supp/wpa_ie.h
size_t lnkid_len;
const u8 *ext_capab;
size_t ext_capab_len;
+ const u8 *supp_rates;
+ size_t supp_rates_len;
+ const u8 *ext_supp_rates;
+ size_t ext_supp_rates_len;
};
int wpa_supplicant_parse_ies(const u8 *buf, size_t len,