atheros: Cleanup atheros_raw_receive to process all management frames

Signed-off-by: Vivek Natarajan <nataraja@qti.qualcomm.com>
This commit is contained in:
Vivek Natarajan 2014-12-01 11:32:45 +05:30 committed by Jouni Malinen
parent c7f35a9e96
commit b685e2aab7

View file

@ -769,145 +769,6 @@ atheros_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr,
return ret; return ret;
} }
#ifdef CONFIG_WPS
static void atheros_raw_recv_wps(void *ctx, const u8 *src_addr, const u8 *buf,
size_t len)
{
struct atheros_driver_data *drv = ctx;
const struct ieee80211_mgmt *mgmt;
u16 fc;
union wpa_event_data event;
/* Send Probe Request information to WPS processing */
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
return;
mgmt = (const struct ieee80211_mgmt *) buf;
fc = le_to_host16(mgmt->frame_control);
if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_PROBE_REQ)
return;
os_memset(&event, 0, sizeof(event));
event.rx_probe_req.sa = mgmt->sa;
event.rx_probe_req.da = mgmt->da;
event.rx_probe_req.bssid = mgmt->bssid;
event.rx_probe_req.ie = mgmt->u.probe_req.variable;
event.rx_probe_req.ie_len =
len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event);
}
#endif /* CONFIG_WPS */
#ifdef CONFIG_IEEE80211R
static void atheros_raw_recv_11r(void *ctx, const u8 *src_addr, const u8 *buf,
size_t len)
{
struct atheros_driver_data *drv = ctx;
union wpa_event_data event;
const struct ieee80211_mgmt *mgmt;
u16 fc;
u16 stype;
int ielen;
const u8 *iebuf;
/* Do 11R processing for ASSOC/AUTH/FT ACTION frames */
if (len < IEEE80211_HDRLEN)
return;
mgmt = (const struct ieee80211_mgmt *) buf;
fc = le_to_host16(mgmt->frame_control);
if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT)
return;
stype = WLAN_FC_GET_STYPE(fc);
wpa_printf(MSG_DEBUG, "%s: subtype 0x%x len %d", __func__, stype,
(int) len);
if (os_memcmp(drv->own_addr, mgmt->bssid, ETH_ALEN) != 0) {
wpa_printf(MSG_DEBUG, "%s: BSSID does not match - ignore",
__func__);
return;
}
switch (stype) {
case WLAN_FC_STYPE_ASSOC_REQ:
if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.assoc_req))
break;
ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
iebuf = mgmt->u.assoc_req.variable;
drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 0);
break;
case WLAN_FC_STYPE_REASSOC_REQ:
if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.reassoc_req))
break;
ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
iebuf = mgmt->u.reassoc_req.variable;
drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 1);
break;
case WLAN_FC_STYPE_ACTION:
os_memset(&event, 0, sizeof(event));
event.rx_mgmt.frame = buf;
event.rx_mgmt.frame_len = len;
wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event);
break;
case WLAN_FC_STYPE_AUTH:
if (len - IEEE80211_HDRLEN < sizeof(mgmt->u.auth))
break;
os_memset(&event, 0, sizeof(event));
os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
os_memcpy(event.auth.bssid, mgmt->bssid, ETH_ALEN);
event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
event.auth.status_code =
le_to_host16(mgmt->u.auth.status_code);
event.auth.auth_transaction =
le_to_host16(mgmt->u.auth.auth_transaction);
event.auth.ies = mgmt->u.auth.variable;
event.auth.ies_len = len - IEEE80211_HDRLEN -
sizeof(mgmt->u.auth);
wpa_supplicant_event(drv->hapd, EVENT_AUTH, &event);
break;
default:
break;
}
}
#endif /* CONFIG_IEEE80211R */
#ifdef CONFIG_HS20
static void atheros_raw_recv_hs20(void *ctx, const u8 *src_addr, const u8 *buf,
size_t len)
{
struct atheros_driver_data *drv = ctx;
const struct ieee80211_mgmt *mgmt;
u16 fc;
union wpa_event_data event;
/* Send the Action frame for HS20 processing */
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.action.category) +
sizeof(mgmt->u.action.u.public_action))
return;
mgmt = (const struct ieee80211_mgmt *) buf;
fc = le_to_host16(mgmt->frame_control);
if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT ||
WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_ACTION ||
mgmt->u.action.category != WLAN_ACTION_PUBLIC)
return;
wpa_printf(MSG_DEBUG, "%s:Received Public Action frame", __func__);
os_memset(&event, 0, sizeof(event));
event.rx_mgmt.frame = (const u8 *) mgmt;
event.rx_mgmt.frame_len = len;
wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event);
}
#endif /* CONFIG_HS20 */
static int atheros_set_qos_map(void *ctx, const u8 *qos_map_set, static int atheros_set_qos_map(void *ctx, const u8 *qos_map_set,
u8 qos_map_set_len) u8 qos_map_set_len)
{ {
@ -957,30 +818,47 @@ static int atheros_set_qos_map(void *ctx, const u8 *qos_map_set,
return 0; return 0;
} }
#if defined(CONFIG_WNM) && !defined(CONFIG_IEEE80211R) #if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) || defined(CONFIG_WNM) || defined(CONFIG_HS20)
static void atheros_raw_recv_11v(void *ctx, const u8 *src_addr, const u8 *buf, static void atheros_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
size_t len) size_t len)
{ {
struct atheros_driver_data *drv = ctx; struct atheros_driver_data *drv = ctx;
union wpa_event_data event;
const struct ieee80211_mgmt *mgmt; const struct ieee80211_mgmt *mgmt;
u16 fc; union wpa_event_data event;
u16 stype; u16 fc, stype;
int ielen;
const u8 *iebuf;
/* Do 11R processing for WNM ACTION frames */
if (len < IEEE80211_HDRLEN) if (len < IEEE80211_HDRLEN)
return; return;
mgmt = (const struct ieee80211_mgmt *) buf; mgmt = (const struct ieee80211_mgmt *) buf;
fc = le_to_host16(mgmt->frame_control); fc = le_to_host16(mgmt->frame_control);
if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT) if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT)
return; return;
stype = WLAN_FC_GET_STYPE(fc); stype = WLAN_FC_GET_STYPE(fc);
wpa_printf(MSG_DEBUG, "%s: subtype 0x%x len %d", __func__, stype, wpa_printf(MSG_DEBUG, "%s: subtype 0x%x len %d", __func__, stype,
(int) len); (int) len);
if (stype == WLAN_FC_STYPE_PROBE_REQ) {
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req))
return;
os_memset(&event, 0, sizeof(event));
event.rx_probe_req.sa = mgmt->sa;
event.rx_probe_req.da = mgmt->da;
event.rx_probe_req.bssid = mgmt->bssid;
event.rx_probe_req.ie = mgmt->u.probe_req.variable;
event.rx_probe_req.ie_len =
len - (IEEE80211_HDRLEN + sizeof(mgmt->u.probe_req));
wpa_supplicant_event(drv->hapd, EVENT_RX_PROBE_REQ, &event);
return;
}
if (os_memcmp(drv->own_addr, mgmt->bssid, ETH_ALEN) != 0) { if (os_memcmp(drv->own_addr, mgmt->bssid, ETH_ALEN) != 0) {
wpa_printf(MSG_DEBUG, "%s: BSSID does not match - ignore", wpa_printf(MSG_DEBUG, "%s: BSSID does not match - ignore",
__func__); __func__);
@ -988,36 +866,47 @@ static void atheros_raw_recv_11v(void *ctx, const u8 *src_addr, const u8 *buf,
} }
switch (stype) { switch (stype) {
case WLAN_FC_STYPE_ASSOC_REQ:
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req))
break;
ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
iebuf = mgmt->u.assoc_req.variable;
drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 0);
break;
case WLAN_FC_STYPE_REASSOC_REQ:
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req))
break;
ielen = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
iebuf = mgmt->u.reassoc_req.variable;
drv_event_assoc(drv->hapd, mgmt->sa, iebuf, ielen, 1);
break;
case WLAN_FC_STYPE_ACTION: case WLAN_FC_STYPE_ACTION:
os_memset(&event, 0, sizeof(event)); os_memset(&event, 0, sizeof(event));
event.rx_mgmt.frame = buf; event.rx_mgmt.frame = buf;
event.rx_mgmt.frame_len = len; event.rx_mgmt.frame_len = len;
wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event); wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event);
break; break;
case WLAN_FC_STYPE_AUTH:
if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth))
break;
os_memset(&event, 0, sizeof(event));
os_memcpy(event.auth.peer, mgmt->sa, ETH_ALEN);
os_memcpy(event.auth.bssid, mgmt->bssid, ETH_ALEN);
event.auth.auth_type = le_to_host16(mgmt->u.auth.auth_alg);
event.auth.status_code =
le_to_host16(mgmt->u.auth.status_code);
event.auth.auth_transaction =
le_to_host16(mgmt->u.auth.auth_transaction);
event.auth.ies = mgmt->u.auth.variable;
event.auth.ies_len = len - IEEE80211_HDRLEN -
sizeof(mgmt->u.auth);
wpa_supplicant_event(drv->hapd, EVENT_AUTH, &event);
break;
default: default:
break; break;
} }
} }
#endif /* CONFIG_WNM */ #endif
#if defined(CONFIG_WPS) || defined(CONFIG_IEEE80211R) || defined(CONFIG_WNM)
static void atheros_raw_receive(void *ctx, const u8 *src_addr, const u8 *buf,
size_t len)
{
#ifdef CONFIG_WPS
atheros_raw_recv_wps(ctx, src_addr, buf, len);
#endif /* CONFIG_WPS */
#ifdef CONFIG_IEEE80211R
atheros_raw_recv_11r(ctx, src_addr, buf, len);
#endif /* CONFIG_IEEE80211R */
#if defined(CONFIG_WNM) && !defined(CONFIG_IEEE80211R)
atheros_raw_recv_11v(ctx, src_addr, buf, len);
#endif /* CONFIG_WNM */
#ifdef CONFIG_HS20
atheros_raw_recv_hs20(ctx, src_addr, buf, len);
#endif /* CONFIG_HS20 */
}
#endif /* CONFIG_WPS || CONFIG_IEEE80211R */
static int atheros_receive_pkt(struct atheros_driver_data *drv) static int atheros_receive_pkt(struct atheros_driver_data *drv)
{ {