From f8b1f695617c8f00e733064f2f7570ed78719da9 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 13 Dec 2009 23:05:39 +0200 Subject: [PATCH] Use generic driver events for TX status and RX reporting Replace driver wrapper calls to hostapd_tx_status(), hostapd_rx_from_unknown_sta(), hostapd_mgmt_rx(), and hostapd_mgmt_tx_cb() with new generic driver events EVENT_TX_STATUS, EVENT_RX_FROM_UNKNOWN, and EVENT_RX_MGMT. This cleans up lot of the driver wrapper code to be less dependent on whether it is being used within wpa_supplicant AP mode or hostapd. --- hostapd/drv_callbacks.c | 269 +++++++++++++++++------------------ hostapd/ieee802_11.c | 75 ++++++++-- hostapd/ieee802_11.h | 7 +- hostapd/ieee802_11_auth.c | 3 +- src/drivers/driver.h | 54 +++++-- src/drivers/driver_hostap.c | 47 +++--- src/drivers/driver_nl80211.c | 79 +++------- src/drivers/driver_test.c | 30 ++-- wpa_supplicant/ap.c | 21 ++- wpa_supplicant/ap.h | 7 + wpa_supplicant/events.c | 33 +++++ 11 files changed, 356 insertions(+), 269 deletions(-) diff --git a/hostapd/drv_callbacks.c b/hostapd/drv_callbacks.c index 278b49519..55c753990 100644 --- a/hostapd/drv_callbacks.c +++ b/hostapd/drv_callbacks.c @@ -116,124 +116,6 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, } -void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, - const u8 *buf, size_t len, int ack) -{ - struct sta_info *sta; - struct hostapd_iface *iface = hapd->iface; - - sta = ap_get_sta(hapd, addr); - if (sta == NULL && iface->num_bss > 1) { - size_t j; - for (j = 0; j < iface->num_bss; j++) { - hapd = iface->bss[j]; - sta = ap_get_sta(hapd, addr); - if (sta) - break; - } - } - if (sta == NULL) - return; - if (sta->flags & WLAN_STA_PENDING_POLL) { - wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending " - "activity poll", MAC2STR(sta->addr), - ack ? "ACKed" : "did not ACK"); - if (ack) - sta->flags &= ~WLAN_STA_PENDING_POLL; - } - - ieee802_1x_tx_status(hapd, sta, buf, len, ack); -} - - -static const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len) -{ - u16 fc, type, stype; - - /* - * PS-Poll frames are 16 bytes. All other frames are - * 24 bytes or longer. - */ - if (len < 16) - return NULL; - - fc = le_to_host16(hdr->frame_control); - type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); - - switch (type) { - case WLAN_FC_TYPE_DATA: - if (len < 24) - return NULL; - switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { - case WLAN_FC_TODS: - return hdr->addr1; - case WLAN_FC_FROMDS: - return hdr->addr2; - default: - return NULL; - } - case WLAN_FC_TYPE_CTRL: - if (stype != WLAN_FC_STYPE_PSPOLL) - return NULL; - return hdr->addr1; - case WLAN_FC_TYPE_MGMT: - return hdr->addr3; - default: - return NULL; - } -} - - -#define HAPD_BROADCAST ((struct hostapd_data *) -1) - -static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, - const u8 *bssid) -{ - size_t i; - - if (bssid == NULL) - return NULL; - if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff && - bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff) - return HAPD_BROADCAST; - - for (i = 0; i < iface->num_bss; i++) { - if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) - return iface->bss[i]; - } - - return NULL; -} - - -void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, - const struct ieee80211_hdr *hdr, size_t len) -{ - struct sta_info *sta; - const u8 *addr; - - hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); - if (hapd == NULL || hapd == HAPD_BROADCAST) - return; - - addr = hdr->addr2; - sta = ap_get_sta(hapd, addr); - if (!sta || !(sta->flags & WLAN_STA_ASSOC)) { - wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated " - "STA " MACSTR, MAC2STR(addr)); - if (sta && (sta->flags & WLAN_STA_AUTH)) - hostapd_sta_disassoc( - hapd, addr, - WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); - else - hostapd_sta_deauth( - hapd, addr, - WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); - } -} - - int hostapd_notif_new_sta(struct hostapd_data *hapd, const u8 *addr) { struct sta_info *sta = ap_get_sta(hapd, addr); @@ -376,9 +258,101 @@ void hostapd_eapol_receive(struct hostapd_data *hapd, const u8 *sa, } +struct hostapd_data * hostapd_sta_get_bss(struct hostapd_data *hapd, + const u8 *addr) +{ + struct hostapd_iface *iface = hapd->iface; + size_t j; + + for (j = 0; j < iface->num_bss; j++) { + hapd = iface->bss[j]; + if (ap_get_sta(hapd, addr)) + return hapd; + } + + return NULL; +} + + +#ifdef HOSTAPD + #ifdef NEED_AP_MLME -void hostapd_mgmt_rx(struct hostapd_data *hapd, u8 *buf, size_t len, - u16 stype, struct hostapd_frame_info *fi) + +static const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len) +{ + u16 fc, type, stype; + + /* + * PS-Poll frames are 16 bytes. All other frames are + * 24 bytes or longer. + */ + if (len < 16) + return NULL; + + fc = le_to_host16(hdr->frame_control); + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + + switch (type) { + case WLAN_FC_TYPE_DATA: + if (len < 24) + return NULL; + switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { + case WLAN_FC_TODS: + return hdr->addr1; + case WLAN_FC_FROMDS: + return hdr->addr2; + default: + return NULL; + } + case WLAN_FC_TYPE_CTRL: + if (stype != WLAN_FC_STYPE_PSPOLL) + return NULL; + return hdr->addr1; + case WLAN_FC_TYPE_MGMT: + return hdr->addr3; + default: + return NULL; + } +} + + +#define HAPD_BROADCAST ((struct hostapd_data *) -1) + +static struct hostapd_data * get_hapd_bssid(struct hostapd_iface *iface, + const u8 *bssid) +{ + size_t i; + + if (bssid == NULL) + return NULL; + if (bssid[0] == 0xff && bssid[1] == 0xff && bssid[2] == 0xff && + bssid[3] == 0xff && bssid[4] == 0xff && bssid[5] == 0xff) + return HAPD_BROADCAST; + + for (i = 0; i < iface->num_bss; i++) { + if (os_memcmp(bssid, iface->bss[i]->own_addr, ETH_ALEN) == 0) + return iface->bss[i]; + } + + return NULL; +} + + +static void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, + const struct ieee80211_hdr *hdr, + size_t len) +{ + hapd = get_hapd_bssid(hapd->iface, get_hdr_bssid(hdr, len)); + if (hapd == NULL || hapd == HAPD_BROADCAST) + return; + + ieee802_11_rx_from_unknown(hapd, hdr->addr2); +} + + +static void hostapd_mgmt_rx(struct hostapd_data *hapd, u8 *buf, + size_t len, struct hostapd_frame_info *fi) { struct hostapd_iface *iface = hapd->iface; struct ieee80211_hdr *hdr; @@ -408,14 +382,14 @@ void hostapd_mgmt_rx(struct hostapd_data *hapd, u8 *buf, size_t len, if (hapd == HAPD_BROADCAST) { size_t i; for (i = 0; i < iface->num_bss; i++) - ieee802_11_mgmt(iface->bss[i], buf, len, stype, fi); + ieee802_11_mgmt(iface->bss[i], buf, len, fi); } else - ieee802_11_mgmt(hapd, buf, len, stype, fi); + ieee802_11_mgmt(hapd, buf, len, fi); } -void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, u8 *buf, size_t len, - u16 stype, int ok) +static void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, const u8 *buf, + size_t len, u16 stype, int ok) { struct ieee80211_hdr *hdr; hdr = (struct ieee80211_hdr *) buf; @@ -424,26 +398,10 @@ void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, u8 *buf, size_t len, return; ieee802_11_mgmt_cb(hapd, buf, len, stype, ok); } + #endif /* NEED_AP_MLME */ -struct hostapd_data * hostapd_sta_get_bss(struct hostapd_data *hapd, - const u8 *addr) -{ - struct hostapd_iface *iface = hapd->iface; - size_t j; - - for (j = 0; j < iface->num_bss; j++) { - hapd = iface->bss[j]; - if (ap_get_sta(hapd, addr)) - return hapd; - } - - return NULL; -} - - -#ifndef CONFIG_AP void wpa_supplicant_event(void *ctx, wpa_event_type event, union wpa_event_data *data) { @@ -466,12 +424,39 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event, case EVENT_WPS_BUTTON_PUSHED: hostapd_wps_button_pushed(hapd); break; +#ifdef NEED_AP_MLME + case EVENT_TX_STATUS: + switch (data->tx_status.type) { + case WLAN_FC_TYPE_MGMT: + hostapd_mgmt_tx_cb(hapd, data->tx_status.data, + data->tx_status.data_len, + data->tx_status.stype, + data->tx_status.ack); + break; + case WLAN_FC_TYPE_DATA: + hostapd_tx_status(hapd, data->tx_status.dst, + data->tx_status.data, + data->tx_status.data_len, + data->tx_status.ack); + break; + } + break; + case EVENT_RX_FROM_UNKNOWN: + hostapd_rx_from_unknown_sta(hapd, data->rx_from_unknown.hdr, + data->rx_from_unknown.len); + break; + case EVENT_RX_MGMT: + hostapd_mgmt_rx(hapd, data->rx_mgmt.frame, + data->rx_mgmt.frame_len, data->rx_mgmt.fi); + break; +#endif /* NEED_AP_MLME */ default: wpa_printf(MSG_DEBUG, "Unknown event %d", event); break; } } -#endif /* CONFIG_AP */ + +#endif /* HOSTAPD */ void hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, diff --git a/hostapd/ieee802_11.c b/hostapd/ieee802_11.c index 63f14294b..a3bffc77c 100644 --- a/hostapd/ieee802_11.c +++ b/hostapd/ieee802_11.c @@ -1053,7 +1053,7 @@ static void handle_assoc(struct hostapd_data *hapd, static void handle_disassoc(struct hostapd_data *hapd, - struct ieee80211_mgmt *mgmt, size_t len) + const struct ieee80211_mgmt *mgmt, size_t len) { struct sta_info *sta; @@ -1102,7 +1102,7 @@ static void handle_disassoc(struct hostapd_data *hapd, static void handle_deauth(struct hostapd_data *hapd, - struct ieee80211_mgmt *mgmt, size_t len) + const struct ieee80211_mgmt *mgmt, size_t len) { struct sta_info *sta; @@ -1338,7 +1338,6 @@ static void handle_action(struct hostapd_data *hapd, * sent to) * @buf: management frame data (starting from IEEE 802.11 header) * @len: length of frame data in octets - * @stype: management frame subtype from frame control field * @fi: meta data about received frame (signal level, etc.) * * Process all incoming IEEE 802.11 management frames. This will be called for @@ -1346,11 +1345,16 @@ static void handle_action(struct hostapd_data *hapd, * addition, it can be called to re-inserted pending frames (e.g., when using * external RADIUS server as an MAC ACL). */ -void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype, +void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len, struct hostapd_frame_info *fi) { - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf; + struct ieee80211_mgmt *mgmt; int broadcast; + u16 fc, stype; + + mgmt = (struct ieee80211_mgmt *) buf; + fc = le_to_host16(mgmt->frame_control); + stype = WLAN_FC_GET_STYPE(fc); if (stype == WLAN_FC_STYPE_BEACON) { handle_beacon(hapd, mgmt, len, fi); @@ -1417,7 +1421,7 @@ void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype, static void handle_auth_cb(struct hostapd_data *hapd, - struct ieee80211_mgmt *mgmt, + const struct ieee80211_mgmt *mgmt, size_t len, int ok) { u16 auth_alg, auth_transaction, status_code; @@ -1458,7 +1462,7 @@ static void handle_auth_cb(struct hostapd_data *hapd, static void handle_assoc_cb(struct hostapd_data *hapd, - struct ieee80211_mgmt *mgmt, + const struct ieee80211_mgmt *mgmt, size_t len, int reassoc, int ok) { u16 status; @@ -1594,10 +1598,11 @@ static void handle_assoc_cb(struct hostapd_data *hapd, * @stype: management frame subtype from frame control field * @ok: Whether the frame was ACK'ed */ -void ieee802_11_mgmt_cb(struct hostapd_data *hapd, u8 *buf, size_t len, +void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len, u16 stype, int ok) { - struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) buf; + const struct ieee80211_mgmt *mgmt; + mgmt = (const struct ieee80211_mgmt *) buf; switch (stype) { case WLAN_FC_STYPE_AUTH: @@ -1642,4 +1647,56 @@ int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta, return 0; } + +void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, + const u8 *buf, size_t len, int ack) +{ + struct sta_info *sta; + struct hostapd_iface *iface = hapd->iface; + + sta = ap_get_sta(hapd, addr); + if (sta == NULL && iface->num_bss > 1) { + size_t j; + for (j = 0; j < iface->num_bss; j++) { + hapd = iface->bss[j]; + sta = ap_get_sta(hapd, addr); + if (sta) + break; + } + } + if (sta == NULL) + return; + if (sta->flags & WLAN_STA_PENDING_POLL) { + wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending " + "activity poll", MAC2STR(sta->addr), + ack ? "ACKed" : "did not ACK"); + if (ack) + sta->flags &= ~WLAN_STA_PENDING_POLL; + } + + ieee802_1x_tx_status(hapd, sta, buf, len, ack); +} + + +void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src) +{ + struct sta_info *sta; + + sta = ap_get_sta(hapd, src); + if (sta && (sta->flags & WLAN_STA_ASSOC)) + return; + + wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA " + MACSTR, MAC2STR(src)); + if (sta && (sta->flags & WLAN_STA_AUTH)) + hostapd_sta_disassoc( + hapd, src, + WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); + else + hostapd_sta_deauth( + hapd, src, + WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); +} + + #endif /* CONFIG_NATIVE_WINDOWS */ diff --git a/hostapd/ieee802_11.h b/hostapd/ieee802_11.h index ed810d39b..93a2a50a4 100644 --- a/hostapd/ieee802_11.h +++ b/hostapd/ieee802_11.h @@ -25,8 +25,8 @@ struct hostapd_frame_info; void ieee802_11_send_deauth(struct hostapd_data *hapd, u8 *addr, u16 reason); void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len, - u16 stype, struct hostapd_frame_info *fi); -void ieee802_11_mgmt_cb(struct hostapd_data *hapd, u8 *buf, size_t len, + struct hostapd_frame_info *fi); +void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len, u16 stype, int ok); void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len); #ifdef NEED_AP_MLME @@ -62,5 +62,8 @@ void hostapd_get_ht_capab(struct hostapd_data *hapd, u16 copy_sta_ht_capab(struct sta_info *sta, const u8 *ht_capab, size_t ht_capab_len); void update_ht_state(struct hostapd_data *hapd, struct sta_info *sta); +void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, + const u8 *buf, size_t len, int ack); +void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src); #endif /* IEEE802_11_H */ diff --git a/hostapd/ieee802_11_auth.c b/hostapd/ieee802_11_auth.c index 092e27ab9..981067c68 100644 --- a/hostapd/ieee802_11_auth.c +++ b/hostapd/ieee802_11_auth.c @@ -470,8 +470,7 @@ hostapd_acl_recv_radius(struct radius_msg *msg, struct radius_msg *req, /* Re-send original authentication frame for 802.11 processing */ wpa_printf(MSG_DEBUG, "Re-sending authentication frame after " "successful RADIUS ACL query"); - ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, - WLAN_FC_STYPE_AUTH, NULL); + ieee802_11_mgmt(hapd, query->auth_msg, query->auth_msg_len, NULL); #endif /* NEED_AP_MLME */ #endif /* CONFIG_DRIVER_RADIUS_ACL */ diff --git a/src/drivers/driver.h b/src/drivers/driver.h index c07a45e6a..c6dbcb286 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1711,7 +1711,22 @@ typedef enum wpa_event_type { /** * EVENT_WPS_BUTTON_PUSHED - Report hardware push button press for WPS */ - EVENT_WPS_BUTTON_PUSHED + EVENT_WPS_BUTTON_PUSHED, + + /** + * EVENT_TX_STATUS - Report TX status + */ + EVENT_TX_STATUS, + + /** + * EVENT_RX_FROM_UNKNOWN - Report RX from unknown STA + */ + EVENT_RX_FROM_UNKNOWN, + + /** + * EVENT_RX_MGMT - Report RX of a management frame + */ + EVENT_RX_MGMT } wpa_event_type; @@ -1902,6 +1917,35 @@ union wpa_event_data { const u8 *data; size_t data_len; } ft_rrb_rx; + + /** + * struct tx_status - Data for EVENT_TX_STATUS events + */ + struct tx_status { + u16 type; + u16 stype; + const u8 *dst; + const u8 *data; + size_t data_len; + int ack; + } tx_status; + + /** + * struct rx_from_unknown - Data for EVENT_RX_FROM_UNKNOWN events + */ + struct rx_from_unknown { + const struct ieee80211_hdr *hdr; + size_t len; + } rx_from_unknown; + + /** + * struct rx_mgmt - Data for EVENT_RX_MGMT events + */ + struct rx_mgmt { + u8 *frame; + size_t frame_len; + struct hostapd_frame_info *fi; + } rx_mgmt; }; /** @@ -1953,10 +1997,6 @@ struct ieee80211_hdr; void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, int reassoc); -void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr, - const u8 *buf, size_t len, int ack); -void hostapd_rx_from_unknown_sta(struct hostapd_data *hapd, - const struct ieee80211_hdr *hdr, size_t len); int hostapd_notif_new_sta(struct hostapd_data *hapd, const u8 *addr); int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, const u8 *ie, size_t ielen); @@ -1970,10 +2010,6 @@ struct hostapd_frame_info { u32 ssi_signal; }; -void hostapd_mgmt_rx(struct hostapd_data *hapd, u8 *buf, size_t len, - u16 stype, struct hostapd_frame_info *fi); -void hostapd_mgmt_tx_cb(struct hostapd_data *hapd, u8 *buf, size_t len, - u16 stype, int ok); struct hostapd_data * hostapd_sta_get_bss(struct hostapd_data *hapd, const u8 *addr); void hostapd_probe_req_rx(struct hostapd_data *hapd, const u8 *sa, diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index 3e376589f..c781bb9e8 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -67,6 +67,7 @@ static void handle_data(struct hostap_driver_data *drv, u8 *buf, size_t len, u16 fc, ethertype; u8 *pos, *sa; size_t left; + union wpa_event_data event; if (len < sizeof(struct ieee80211_hdr)) return; @@ -80,7 +81,10 @@ static void handle_data(struct hostap_driver_data *drv, u8 *buf, size_t len, } sa = hdr->addr2; - hostapd_rx_from_unknown_sta(drv->hapd, hdr, len); + os_memset(&event, 0, sizeof(event)); + event.rx_from_unknown.hdr = hdr; + event.rx_from_unknown.len = len; + wpa_supplicant_event(drv->hapd, EVENT_RX_FROM_UNKNOWN, &event); pos = (u8 *) (hdr + 1); left = len - sizeof(*hdr); @@ -121,33 +125,20 @@ static void handle_tx_callback(struct hostap_driver_data *drv, u8 *buf, size_t len, int ok) { struct ieee80211_hdr *hdr; - u16 fc, type, stype; + u16 fc; + union wpa_event_data event; hdr = (struct ieee80211_hdr *) buf; fc = le_to_host16(hdr->frame_control); - type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); - - switch (type) { - case WLAN_FC_TYPE_MGMT: - wpa_printf(MSG_DEBUG, "MGMT (TX callback) %s", - ok ? "ACK" : "fail"); - hostapd_mgmt_tx_cb(drv->hapd, buf, len, stype, ok); - break; - case WLAN_FC_TYPE_CTRL: - wpa_printf(MSG_DEBUG, "CTRL (TX callback) %s", - ok ? "ACK" : "fail"); - break; - case WLAN_FC_TYPE_DATA: - wpa_printf(MSG_DEBUG, "DATA (TX callback) %s", - ok ? "ACK" : "fail"); - hostapd_tx_status(drv->hapd, hdr->addr1, buf, len, ok); - break; - default: - printf("unknown TX callback frame type %d\n", type); - break; - } + os_memset(&event, 0, sizeof(event)); + event.tx_status.type = WLAN_FC_GET_TYPE(fc); + event.tx_status.stype = WLAN_FC_GET_STYPE(fc); + event.tx_status.dst = hdr->addr1; + event.tx_status.data = buf; + event.tx_status.data_len = len; + event.tx_status.ack = ok; + wpa_supplicant_event(drv->hapd, EVENT_TX_STATUS, &event); } @@ -158,6 +149,7 @@ static void handle_frame(struct hostap_driver_data *drv, u8 *buf, size_t len) unsigned char *extra = NULL; size_t data_len = len; int ver; + union wpa_event_data event; /* PSPOLL is only 16 bytes, but driver does not (at least yet) pass * these to user space */ @@ -202,9 +194,10 @@ static void handle_frame(struct hostap_driver_data *drv, u8 *buf, size_t len) switch (type) { case WLAN_FC_TYPE_MGMT: - if (stype != WLAN_FC_STYPE_BEACON) - wpa_printf(MSG_MSGDUMP, "MGMT"); - hostapd_mgmt_rx(drv->hapd, buf, data_len, stype, NULL); + os_memset(&event, 0, sizeof(event)); + event.rx_mgmt.frame = buf; + event.rx_mgmt.frame_len = data_len; + wpa_supplicant_event(drv->hapd, EVENT_RX_MGMT, &event); break; case WLAN_FC_TYPE_CTRL: wpa_printf(MSG_DEBUG, "CTRL"); diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 7ba055794..1f5e21c16 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -2819,66 +2819,34 @@ static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv, } -#ifdef CONFIG_AP - -void ap_tx_status(void *ctx, const u8 *addr, - const u8 *buf, size_t len, int ack); -void ap_rx_from_unknown_sta(void *ctx, struct ieee80211_hdr *hdr, size_t len); -void ap_mgmt_rx(void *ctx, u8 *buf, size_t len, u16 stype, - struct hostapd_frame_info *fi); -void ap_mgmt_tx_cb(void *ctx, u8 *buf, size_t len, u16 stype, int ok); - -#endif /* CONFIG_AP */ - - static void handle_tx_callback(void *ctx, u8 *buf, size_t len, int ok) { struct ieee80211_hdr *hdr; - u16 fc, type, stype; + u16 fc; + union wpa_event_data event; hdr = (struct ieee80211_hdr *) buf; fc = le_to_host16(hdr->frame_control); - type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); - - switch (type) { - case WLAN_FC_TYPE_MGMT: - wpa_printf(MSG_DEBUG, "MGMT (TX callback) %s", - ok ? "ACK" : "fail"); -#ifdef HOSTAPD - hostapd_mgmt_tx_cb(ctx, buf, len, stype, ok); -#elif CONFIG_AP - ap_mgmt_tx_cb(ctx, buf, len, stype, ok); -#endif - break; - case WLAN_FC_TYPE_CTRL: - wpa_printf(MSG_DEBUG, "CTRL (TX callback) %s", - ok ? "ACK" : "fail"); - break; - case WLAN_FC_TYPE_DATA: -#ifdef HOSTAPD - hostapd_tx_status(ctx, hdr->addr1, buf, len, ok); -#elif CONFIG_AP - ap_tx_status(ctx, hdr->addr1, buf, len, ok); -#endif - break; - default: - wpa_printf(MSG_DEBUG, "unknown TX callback frame type %d", - type); - break; - } + os_memset(&event, 0, sizeof(event)); + event.tx_status.type = WLAN_FC_GET_TYPE(fc); + event.tx_status.stype = WLAN_FC_GET_STYPE(fc); + event.tx_status.dst = hdr->addr1; + event.tx_status.data = buf; + event.tx_status.data_len = len; + event.tx_status.ack = ok; + wpa_supplicant_event(ctx, EVENT_TX_STATUS, &event); } static void from_unknown_sta(struct wpa_driver_nl80211_data *drv, struct ieee80211_hdr *hdr, size_t len) { -#ifdef HOSTAPD - hostapd_rx_from_unknown_sta(drv->ctx, hdr, len); -#elif CONFIG_AP - ap_rx_from_unknown_sta(drv->ctx, hdr, len); -#endif + union wpa_event_data event; + os_memset(&event, 0, sizeof(event)); + event.rx_from_unknown.hdr = hdr; + event.rx_from_unknown.len = len; + wpa_supplicant_event(drv->ctx, EVENT_RX_FROM_UNKNOWN, &event); } @@ -2887,22 +2855,19 @@ static void handle_frame(struct wpa_driver_nl80211_data *drv, struct hostapd_frame_info *hfi) { struct ieee80211_hdr *hdr; - u16 fc, stype; + u16 fc; + union wpa_event_data event; hdr = (struct ieee80211_hdr *) buf; fc = le_to_host16(hdr->frame_control); - stype = WLAN_FC_GET_STYPE(fc); switch (WLAN_FC_GET_TYPE(fc)) { case WLAN_FC_TYPE_MGMT: - if (stype != WLAN_FC_STYPE_BEACON && - stype != WLAN_FC_STYPE_PROBE_REQ) - wpa_printf(MSG_MSGDUMP, "MGMT"); -#ifdef HOSTAPD - hostapd_mgmt_rx(drv->ctx, buf, len, stype, hfi); -#elif CONFIG_AP - ap_mgmt_rx(drv->ctx, buf, len, stype, hfi); -#endif + os_memset(&event, 0, sizeof(event)); + event.rx_mgmt.frame = buf; + event.rx_mgmt.frame_len = len; + event.rx_mgmt.fi = hfi; + wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event); break; case WLAN_FC_TYPE_CTRL: /* can only get here with PS-Poll frames */ diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index d95503369..4882641f3 100644 --- a/src/drivers/driver_test.c +++ b/src/drivers/driver_test.c @@ -317,6 +317,7 @@ static int wpa_driver_test_send_mlme(void *priv, const u8 *data, #ifdef HOSTAPD char desttxt[30]; #endif /* HOSTAPD */ + union wpa_event_data event; wpa_hexdump(MSG_MSGDUMP, "test_send_mlme", data, data_len); if (drv->test_socket < 0 || data_len < 10) { @@ -456,15 +457,15 @@ static int wpa_driver_test_send_mlme(void *priv, const u8 *data, hdr = (struct ieee80211_hdr *) data; fc = le_to_host16(hdr->frame_control); -#ifdef HOSTAPD - hostapd_mgmt_tx_cb(drv->ctx, (u8 *) data, data_len, - WLAN_FC_GET_STYPE(fc), ret >= 0); -#else /* HOSTAPD */ - if (drv->ap) { - ap_mgmt_tx_cb(drv->ctx, (u8 *) data, data_len, - WLAN_FC_GET_STYPE(fc), ret >= 0); - } -#endif /* HOSTAPD */ + + os_memset(&event, 0, sizeof(event)); + event.tx_status.type = WLAN_FC_GET_TYPE(fc); + event.tx_status.stype = WLAN_FC_GET_STYPE(fc); + event.tx_status.dst = hdr->addr1; + event.tx_status.data = data; + event.tx_status.data_len = data_len; + event.tx_status.ack = ret >= 0; + wpa_supplicant_event(drv->ctx, EVENT_TX_STATUS, &event); return ret; } @@ -705,6 +706,7 @@ static void test_driver_mlme(struct wpa_driver_test_data *drv, { struct ieee80211_hdr *hdr; u16 fc; + union wpa_event_data event; hdr = (struct ieee80211_hdr *) data; @@ -730,11 +732,11 @@ static void test_driver_mlme(struct wpa_driver_test_data *drv, __func__); return; } -#ifdef HOSTAPD - hostapd_mgmt_rx(drv->ctx, data, datalen, WLAN_FC_GET_STYPE(fc), NULL); -#else /* HOSTAPD */ - ap_mgmt_rx(drv->ctx, data, datalen, WLAN_FC_GET_STYPE(fc), NULL); -#endif /* HOSTAPD */ + + os_memset(&event, 0, sizeof(event)); + event.rx_mgmt.frame = data; + event.rx_mgmt.frame_len = datalen; + wpa_supplicant_event(drv->ctx, EVENT_RX_MGMT, &event); } diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index 039e64f64..2e0882a57 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -484,33 +484,40 @@ void wpa_supplicant_ap_deinit(struct wpa_supplicant *wpa_s) void ap_tx_status(void *ctx, const u8 *addr, const u8 *buf, size_t len, int ack) { +#ifdef NEED_AP_MLME struct wpa_supplicant *wpa_s = ctx; hostapd_tx_status(wpa_s->ap_iface->bss[0], addr, buf, len, ack); +#endif /* NEED_AP_MLME */ } -void ap_rx_from_unknown_sta(void *ctx, struct ieee80211_hdr *hdr, size_t len) +void ap_rx_from_unknown_sta(void *ctx, const struct ieee80211_hdr *hdr, + size_t len) { +#ifdef NEED_AP_MLME struct wpa_supplicant *wpa_s = ctx; - hostapd_rx_from_unknown_sta(wpa_s->ap_iface->bss[0], hdr, len); + ieee802_11_rx_from_unknown(wpa_s->ap_iface->bss[0], hdr->addr2); +#endif /* NEED_AP_MLME */ } -#ifdef NEED_AP_MLME -void ap_mgmt_rx(void *ctx, u8 *buf, size_t len, u16 stype, +void ap_mgmt_rx(void *ctx, u8 *buf, size_t len, struct hostapd_frame_info *fi) { +#ifdef NEED_AP_MLME struct wpa_supplicant *wpa_s = ctx; - ieee802_11_mgmt(wpa_s->ap_iface->bss[0], buf, len, stype, fi); + ieee802_11_mgmt(wpa_s->ap_iface->bss[0], buf, len, fi); +#endif /* NEED_AP_MLME */ } -void ap_mgmt_tx_cb(void *ctx, u8 *buf, size_t len, u16 stype, int ok) +void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok) { +#ifdef NEED_AP_MLME struct wpa_supplicant *wpa_s = ctx; ieee802_11_mgmt_cb(wpa_s->ap_iface->bss[0], buf, len, stype, ok); -} #endif /* NEED_AP_MLME */ +} void wpa_supplicant_ap_rx_eapol(struct wpa_supplicant *wpa_s, diff --git a/wpa_supplicant/ap.h b/wpa_supplicant/ap.h index 91dca8e4f..487de45af 100644 --- a/wpa_supplicant/ap.h +++ b/wpa_supplicant/ap.h @@ -32,5 +32,12 @@ int ap_ctrl_iface_sta_next(struct wpa_supplicant *wpa_s, const char *txtaddr, char *buf, size_t buflen); int ap_ctrl_iface_wpa_get_status(struct wpa_supplicant *wpa_s, char *buf, size_t buflen, int verbose); +void ap_tx_status(void *ctx, const u8 *addr, + const u8 *buf, size_t len, int ack); +void ap_rx_from_unknown_sta(void *ctx, const struct ieee80211_hdr *hdr, + size_t len); +void ap_mgmt_rx(void *ctx, u8 *buf, size_t len, + struct hostapd_frame_info *fi); +void ap_mgmt_tx_cb(void *ctx, const u8 *buf, size_t len, u16 stype, int ok); #endif /* AP_H */ diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index c5283900e..f8141ebd6 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -35,6 +35,7 @@ #include "ibss_rsn.h" #include "sme.h" #include "bgscan.h" +#include "ap.h" static int wpa_supplicant_select_config(struct wpa_supplicant *wpa_s) @@ -1433,6 +1434,38 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event, case EVENT_ASSOC_TIMED_OUT: sme_event_assoc_timed_out(wpa_s, data); break; +#ifdef CONFIG_AP + case EVENT_TX_STATUS: + if (wpa_s->ap_iface == NULL) + break; + switch (data->tx_status.type) { + case WLAN_FC_TYPE_MGMT: + ap_mgmt_tx_cb(wpa_s, data->tx_status.data, + data->tx_status.data_len, + data->tx_status.stype, + data->tx_status.ack); + break; + case WLAN_FC_TYPE_DATA: + ap_tx_status(wpa_s, data->tx_status.dst, + data->tx_status.data, + data->tx_status.data_len, + data->tx_status.ack); + break; + } + break; + case EVENT_RX_FROM_UNKNOWN: + if (wpa_s->ap_iface == NULL) + break; + ap_rx_from_unknown_sta(wpa_s, data->rx_from_unknown.hdr, + data->rx_from_unknown.len); + break; + case EVENT_RX_MGMT: + if (wpa_s->ap_iface == NULL) + break; + ap_mgmt_rx(wpa_s, data->rx_mgmt.frame, + data->rx_mgmt.frame_len, data->rx_mgmt.fi); + break; +#endif /* CONFIG_AP */ default: wpa_printf(MSG_INFO, "Unknown event %d", event); break;