diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index 10315adb6..e6f13f807 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -320,17 +320,14 @@ static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, - const u8 *frame, size_t len) + const u8 *bssid, const u8 *addr, + int wds) { - const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) frame; - u16 fc = le_to_host16(hdr->frame_control); - hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); + hapd = get_hapd_bssid(hapd->iface, bssid); if (hapd == NULL || hapd == HAPD_BROADCAST) return; - ieee802_11_rx_from_unknown(hapd, hdr->addr2, - (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == - (WLAN_FC_TODS | WLAN_FC_FROMDS)); + ieee802_11_rx_from_unknown(hapd, addr, wds); } @@ -513,8 +510,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, hostapd_client_poll_ok(hapd, data->client_poll.addr); break; case EVENT_RX_FROM_UNKNOWN: - hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.frame, - data->rx_from_unknown.len); + hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.bssid, + data->rx_from_unknown.addr, + data->rx_from_unknown.wds); break; case EVENT_RX_MGMT: hostapd_mgmt_rx(hapd, &data->rx_mgmt); diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 3c0ef2ae2..7009289ed 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -3234,8 +3234,9 @@ union wpa_event_data { * struct rx_from_unknown - Data for EVENT_RX_FROM_UNKNOWN events */ struct rx_from_unknown { - const u8 *frame; - size_t len; + const u8 *bssid; + const u8 *addr; + int wds; } rx_from_unknown; /** diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index 7a97ed529..85e925139 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -32,6 +32,7 @@ #include "netlink.h" #include "linux_ioctl.h" #include "common/ieee802_11_defs.h" +#include "common/ieee802_11_common.h" /* MTU to be set for the wlan#ap device; this is mainly needed for IEEE 802.1X @@ -84,8 +85,8 @@ static void handle_data(struct hostap_driver_data *drv, u8 *buf, size_t len, sa = hdr->addr2; os_memset(&event, 0, sizeof(event)); - event.rx_from_unknown.frame = buf; - event.rx_from_unknown.len = len; + event.rx_from_unknown.bssid = get_hdr_bssid(hdr, len); + event.rx_from_unknown.addr = sa; wpa_supplicant_event(drv->hapd, EVENT_RX_FROM_UNKNOWN, &event); pos = (u8 *) (hdr + 1); diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 90a55cd24..0797d49eb 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -34,6 +34,7 @@ #include "eloop.h" #include "utils/list.h" #include "common/ieee802_11_defs.h" +#include "common/ieee802_11_common.h" #include "l2_packet/l2_packet.h" #include "netlink.h" #include "linux_ioctl.h" @@ -4661,10 +4662,20 @@ static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok) static void from_unknown_sta(struct wpa_driver_nl80211_data *drv, u8 *buf, size_t len) { + struct ieee80211_hdr *hdr = (void *)buf; + u16 fc; union wpa_event_data event; + + if (len < sizeof(*hdr)) + return; + + fc = le_to_host16(hdr->frame_control); + os_memset(&event, 0, sizeof(event)); - event.rx_from_unknown.frame = buf; - event.rx_from_unknown.len = len; + event.rx_from_unknown.bssid = get_hdr_bssid(hdr, len); + event.rx_from_unknown.addr = hdr->addr2; + event.rx_from_unknown.wds = (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) == + (WLAN_FC_FROMDS | WLAN_FC_TODS); wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event); } diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 8f83a6bae..c4959bf1d 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -576,16 +576,11 @@ void ap_client_poll_ok(void *ctx, const u8 *addr) } -void ap_rx_from_unknown_sta(void *ctx, const u8 *frame, size_t len) +void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds) { #ifdef NEED_AP_MLME struct wpa_supplicant *wpa_s = ctx; - const struct ieee80211_hdr *hdr = - (const struct ieee80211_hdr *) frame; - u16 fc = le_to_host16(hdr->frame_control); - ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], hdr->addr2, - (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == - (WLAN_FC_TODS | WLAN_FC_FROMDS)); + ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], addr, wds); #endif /* NEED_AP_MLME */ } diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h index b94ead7f0..567e784e5 100644 --- a/wpa_supplicant/ap.h +++ b/wpa_supplicant/ap.h @@ -42,7 +42,7 @@ int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf, void ap_tx_status(void *ctx, const u8 *addr, const u8 *buf, size_t len, int ack); void ap_client_poll_ok(void *ctx, const u8 *addr); -void ap_rx_from_unknown_sta(void *ctx, const u8 *frame, size_t len); +void ap_rx_from_unknown_sta(void *ctx, const u8 *addr, int wds); void ap_mgmt_rx(void *ctx, struct rx_mgmt *rx_mgmt); void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok); int wpa_supplicant_ap_update_beacon(struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 232a7768f..4ec935e55 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2033,8 +2033,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, case EVENT_RX_FROM_UNKNOWN: if (wpa_s->ap_iface == NULL) break; - ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.frame, - data->rx_from_unknown.len); + ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.addr, + data->rx_from_unknown.wds); break; case EVENT_RX_MGMT: if (wpa_s->ap_iface == NULL) {