From 1d041bec843d55cd6be7be61ba83ddf96c5e2368 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 3 Jan 2010 18:22:22 +0200 Subject: [PATCH] Use generic driver event notification for AP mode assoc/disassoc --- src/ap/drv_callbacks.c | 13 ++++++++ src/ap/hostapd.h | 5 +++ src/drivers/driver.h | 60 +++++++++++++++++++++++++++++++---- src/drivers/driver_atheros.c | 12 +++---- src/drivers/driver_broadcom.c | 21 +++++------- src/drivers/driver_bsd.c | 6 ++-- src/drivers/driver_madwifi.c | 12 +++---- src/drivers/driver_ralink.c | 24 +++++++------- src/drivers/driver_test.c | 9 ++---- src/drivers/driver_wext.c | 29 +++++++++-------- wpa_supplicant/events.c | 28 +++++++++++++++- 11 files changed, 148 insertions(+), 71 deletions(-) diff --git a/src/ap/drv_callbacks.c b/src/ap/drv_callbacks.c index b03a54154..61ca690e6 100644 --- a/src/ap/drv_callbacks.c +++ b/src/ap/drv_callbacks.c @@ -397,6 +397,19 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, data->eapol_rx.data, data->eapol_rx.data_len); break; + case EVENT_ASSOC: + hostapd_notif_assoc(hapd, data->assoc_info.addr, + data->assoc_info.req_ies, + data->assoc_info.req_ies_len); + break; + case EVENT_DISASSOC: + if (data) + hostapd_notif_disassoc(hapd, data->disassoc_info.addr); + break; + case EVENT_DEAUTH: + if (data) + hostapd_notif_disassoc(hapd, data->deauth_info.addr); + break; default: wpa_printf(MSG_DEBUG, "Unknown event %d", event); break; diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 86676ff20..7c6b0b77c 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -260,4 +260,9 @@ int hostapd_register_probereq_cb(struct hostapd_data *hapd, void *ctx); void hostapd_prune_associations(struct hostapd_data *hapd, const u8 *addr); +/* drv_callbacks.c (TODO: move to somewhere else?) */ +int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, + const u8 *ie, size_t ielen); +void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr); + #endif /* HOSTAPD_H */ diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 77263b578..e338c0fdc 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1651,6 +1651,7 @@ enum wpa_event_type { * sending either of these frames to the current AP. If the driver * supports separate deauthentication event, EVENT_DISASSOC should only * be used for disassociation and EVENT_DEAUTH for deauthentication. + * In AP mode, union wpa_event_data::disassoc_info is required. */ EVENT_DISASSOC, @@ -1778,6 +1779,7 @@ enum wpa_event_type { * This event should be called when authentication is lost either due * to receiving deauthenticate frame from the AP or when sending that * frame to the current AP. + * In AP mode, union wpa_event_data::deauth_info is required. */ EVENT_DEAUTH, @@ -1920,7 +1922,7 @@ union wpa_event_data { * This should start with the first IE (fixed fields before IEs * are not included). */ - u8 *req_ies; + const u8 *req_ies; /** * req_ies_len - Length of req_ies in bytes @@ -1938,7 +1940,7 @@ union wpa_event_data { * This should start with the first IE (fixed fields before IEs * are not included). */ - u8 *resp_ies; + const u8 *resp_ies; /** * resp_ies_len - Length of resp_ies in bytes @@ -1961,7 +1963,7 @@ union wpa_event_data { * This should start with the first IE (fixed fields before IEs * are not included). */ - u8 *beacon_ies; + const u8 *beacon_ies; /** * beacon_ies_len - Length of beacon_ies */ @@ -1971,8 +1973,33 @@ union wpa_event_data { * freq - Frequency of the operational channel in MHz */ unsigned int freq; + + /** + * addr - Station address (for AP mode) + */ + const u8 *addr; } assoc_info; + /** + * struct disassoc_info - Data for EVENT_DISASSOC events + */ + struct disassoc_info { + /** + * addr - Station address (for AP mode) + */ + const u8 *addr; + } disassoc_info; + + /** + * struct deauth_info - Data for EVENT_DEAUTH events + */ + struct deauth_info { + /** + * addr - Station address (for AP mode) + */ + const u8 *addr; + } deauth_info; + /** * struct michael_mic_failure - Data for EVENT_MICHAEL_MIC_FAILURE */ @@ -2253,10 +2280,29 @@ int wpa_scan_get_max_rate(const struct wpa_scan_res *res); void wpa_scan_results_free(struct wpa_scan_results *res); void wpa_scan_sort_results(struct wpa_scan_results *res); -/* hostapd functions for driver wrappers */ -int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr, - const u8 *ie, size_t ielen); -void hostapd_notif_disassoc(struct hostapd_data *hapd, const u8 *addr); +/* + * The following inline functions are provided for convenience to simplify + * event indication for some of the common events. + */ + +static inline void drv_event_assoc(void *ctx, const u8 *addr, const u8 *ie, + size_t ielen) +{ + union wpa_event_data event; + os_memset(&event, 0, sizeof(event)); + event.assoc_info.req_ies = ie; + event.assoc_info.req_ies_len = ielen; + event.assoc_info.addr = addr; + wpa_supplicant_event(ctx, EVENT_ASSOC, &event); +} + +static inline void drv_event_disassoc(void *ctx, const u8 *addr) +{ + union wpa_event_data event; + os_memset(&event, 0, sizeof(event)); + event.disassoc_info.addr = addr; + wpa_supplicant_event(ctx, EVENT_DISASSOC, &event); +} #endif /* DRIVER_H */ diff --git a/src/drivers/driver_atheros.c b/src/drivers/driver_atheros.c index e3a7e7d2f..1e72ec5de 100644 --- a/src/drivers/driver_atheros.c +++ b/src/drivers/driver_atheros.c @@ -732,12 +732,12 @@ madwifi_set_ap_wps_ie(const char *ifname, void *priv, #define madwifi_set_ap_wps_ie NULL #endif /* CONFIG_WPS */ -static int +static void madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) { struct hostapd_data *hapd = drv->hapd; struct ieee80211req_wpaie ie; - int ielen = 0, res; + int ielen = 0; u8 *iebuf = NULL; /* @@ -778,15 +778,13 @@ madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) ielen += 2; no_ie: - res = hostapd_notif_assoc(hapd, addr, iebuf, ielen); + drv_event_assoc(hapd, addr, iebuf, ielen); if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { /* Cached accounting data is not valid anymore. */ memset(drv->acct_mac, 0, ETH_ALEN); memset(&drv->acct_data, 0, sizeof(drv->acct_data)); } - - return res; } static void @@ -904,8 +902,8 @@ madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, switch (iwe->cmd) { case IWEVEXPIRED: - hostapd_notif_disassoc(drv->hapd, - (u8 *) iwe->u.addr.sa_data); + drv_event_disassoc(drv->hapd, + (u8 *) iwe->u.addr.sa_data); break; case IWEVREGISTERED: madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data); diff --git a/src/drivers/driver_broadcom.c b/src/drivers/driver_broadcom.c index 9b9644f3f..cb88543c2 100644 --- a/src/drivers/driver_broadcom.c +++ b/src/drivers/driver_broadcom.c @@ -233,7 +233,8 @@ static void wpa_driver_broadcom_event_receive(int sock, void *ctx, int left; wl_wpa_header_t *wwh; union wpa_event_data data; - + u8 *resp_ies = NULL; + if ((left = recv(sock, buf, sizeof buf, 0)) < 0) return; @@ -257,21 +258,16 @@ static void wpa_driver_broadcom_event_receive(int sock, void *ctx, wpa_printf(MSG_DEBUG, "BROADCOM: ASSOC MESSAGE (left: %d)", left); if (left > 0) { - data.assoc_info.resp_ies = os_malloc(left); - if (data.assoc_info.resp_ies == NULL) + resp_ies = os_malloc(left); + if (resp_ies == NULL) return; - os_memcpy(data.assoc_info.resp_ies, - buf + WL_WPA_HEADER_LEN, left); + os_memcpy(resp_ies, buf + WL_WPA_HEADER_LEN, left); + data.assoc_info.resp_ies = resp_ies; data.assoc_info.resp_ies_len = left; - wpa_hexdump(MSG_MSGDUMP, "BROADCOM: copying %d bytes " - "into resp_ies", - data.assoc_info.resp_ies, left); } - /* data.assoc_info.req_ies = NULL; */ - /* data.assoc_info.req_ies_len = 0; */ - wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); - wpa_supplicant_event(ctx, EVENT_ASSOC, NULL); + wpa_supplicant_event(ctx, EVENT_ASSOC, &data); + os_free(resp_ies); break; case WLC_DISASSOC_MSG: wpa_printf(MSG_DEBUG, "BROADCOM: DISASSOC MESSAGE"); @@ -292,7 +288,6 @@ static void wpa_driver_broadcom_event_receive(int sock, void *ctx, wwh->type); break; } - os_free(data.assoc_info.resp_ies); } static void * wpa_driver_broadcom_init(void *ctx, const char *ifname) diff --git a/src/drivers/driver_bsd.c b/src/drivers/driver_bsd.c index 5b232fd69..ab01370c9 100644 --- a/src/drivers/driver_bsd.c +++ b/src/drivers/driver_bsd.c @@ -569,7 +569,7 @@ bsd_sta_disassoc(void *priv, const u8 *own_addr, const u8 *addr, return set80211var(drv, IEEE80211_IOC_MLME, &mlme, sizeof(mlme)); } -static int +static void bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) { struct hostapd_data *hapd = drv->hapd; @@ -594,7 +594,7 @@ bsd_new_sta(struct bsd_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) ielen += 2; no_ie: - return hostapd_notif_assoc(hapd, addr, iebuf, ielen); + drv_event_assoc(hapd, addr, iebuf, ielen); } static void @@ -634,7 +634,7 @@ bsd_wireless_event_receive(int sock, void *ctx, void *sock_ctx) break; case RTM_IEEE80211_LEAVE: leave = (struct ieee80211_leave_event *) &ifan[1]; - hostapd_notif_disassoc(drv->hapd, leave->iev_addr); + drv_event_notif_disassoc(drv->hapd, leave->iev_addr); break; case RTM_IEEE80211_JOIN: #ifdef RTM_IEEE80211_REJOIN diff --git a/src/drivers/driver_madwifi.c b/src/drivers/driver_madwifi.c index 5c25ee3a9..67efaabd2 100644 --- a/src/drivers/driver_madwifi.c +++ b/src/drivers/driver_madwifi.c @@ -835,12 +835,12 @@ madwifi_set_ap_wps_ie(const char *ifname, void *priv, #define madwifi_set_ap_wps_ie NULL #endif /* CONFIG_WPS */ -static int +static void madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) { struct hostapd_data *hapd = drv->hapd; struct ieee80211req_wpaie ie; - int ielen = 0, res; + int ielen = 0; u8 *iebuf = NULL; /* @@ -879,15 +879,13 @@ madwifi_new_sta(struct madwifi_driver_data *drv, u8 addr[IEEE80211_ADDR_LEN]) ielen += 2; no_ie: - res = hostapd_notif_assoc(hapd, addr, iebuf, ielen); + drv_event_assoc(hapd, addr, iebuf, ielen); if (memcmp(addr, drv->acct_mac, ETH_ALEN) == 0) { /* Cached accounting data is not valid anymore. */ memset(drv->acct_mac, 0, ETH_ALEN); memset(&drv->acct_data, 0, sizeof(drv->acct_data)); } - - return res; } static void @@ -980,8 +978,8 @@ madwifi_wireless_event_wireless(struct madwifi_driver_data *drv, switch (iwe->cmd) { case IWEVEXPIRED: - hostapd_notif_disassoc(drv->hapd, - (u8 *) iwe->u.addr.sa_data); + drv_event_disassoc(drv->hapd, + (u8 *) iwe->u.addr.sa_data); break; case IWEVREGISTERED: madwifi_new_sta(drv, (u8 *) iwe->u.addr.sa_data); diff --git a/src/drivers/driver_ralink.c b/src/drivers/driver_ralink.c index e7fbfb657..6eebdd667 100644 --- a/src/drivers/driver_ralink.c +++ b/src/drivers/driver_ralink.c @@ -452,6 +452,7 @@ wpa_driver_ralink_event_wireless_custom(struct wpa_driver_ralink_data *drv, void *ctx, char *custom) { union wpa_event_data data; + u8 *req_ies = NULL, *resp_ies = NULL; wpa_printf(MSG_DEBUG, "%s", __FUNCTION__); @@ -480,12 +481,12 @@ wpa_driver_ralink_event_wireless_custom(struct wpa_driver_ralink_data *drv, */ bytes = drv->assoc_req_ies_len; - data.assoc_info.req_ies = os_malloc(bytes); - if (data.assoc_info.req_ies == NULL) + req_ies = os_malloc(bytes); + if (req_ies == NULL) return; - + os_memcpy(req_ies, spos, bytes); + data.assoc_info.req_ies = req_ies; data.assoc_info.req_ies_len = bytes; - os_memcpy(data.assoc_info.req_ies, spos, bytes); /* skip the '\0' byte */ spos += bytes + 1; @@ -501,21 +502,20 @@ wpa_driver_ralink_event_wireless_custom(struct wpa_driver_ralink_data *drv, if (!bytes) goto done; - - data.assoc_info.resp_ies = os_malloc(bytes); - if (data.assoc_info.resp_ies == NULL) + resp_ies = os_malloc(bytes); + if (resp_ies == NULL) goto done; - + os_memcpy(resp_ies, spos, bytes); + data.assoc_info.resp_ies = resp_ies; data.assoc_info.resp_ies_len = bytes; - os_memcpy(data.assoc_info.resp_ies, spos, bytes); } wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); - /* free allocated memory */ done: - os_free(data.assoc_info.resp_ies); - os_free(data.assoc_info.req_ies); + /* free allocated memory */ + os_free(resp_ies); + os_free(req_ies); } } diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index c61535ea7..818c19718 100644 --- a/src/drivers/driver_test.c +++ b/src/drivers/driver_test.c @@ -622,10 +622,7 @@ static void test_driver_assoc(struct wpa_driver_test_data *drv, sendto(drv->test_socket, cmd, strlen(cmd), 0, (struct sockaddr *) from, fromlen); -#ifdef HOSTAPD - if (hostapd_notif_assoc(bss->bss_ctx, cli->addr, ie, ielen) < 0) - wpa_printf(MSG_DEBUG, "test_driver: failed to add new STA"); -#endif /* HOSTAPD */ + drv_event_assoc(bss->bss_ctx, cli->addr, ie, ielen); } @@ -638,9 +635,7 @@ static void test_driver_disassoc(struct wpa_driver_test_data *drv, if (!cli) return; -#ifdef HOSTAPD - hostapd_notif_disassoc(drv->ctx, cli->addr); -#endif /* HOSTAPD */ + drv_event_disassoc(drv->ctx, cli->addr); } diff --git a/src/drivers/driver_wext.c b/src/drivers/driver_wext.c index 5bc2efee0..210e29bcf 100644 --- a/src/drivers/driver_wext.c +++ b/src/drivers/driver_wext.c @@ -246,6 +246,7 @@ wpa_driver_wext_event_wireless_custom(void *ctx, char *custom) } else if (os_strncmp(custom, "ASSOCINFO(ReqIEs=", 17) == 0) { char *spos; int bytes; + u8 *req_ies = NULL, *resp_ies = NULL; spos = custom + 17; @@ -254,12 +255,12 @@ wpa_driver_wext_event_wireless_custom(void *ctx, char *custom) return; bytes /= 2; - data.assoc_info.req_ies = os_malloc(bytes); - if (data.assoc_info.req_ies == NULL) + req_ies = os_malloc(bytes); + if (req_ies == NULL) return; - + hexstr2bin(spos, req_ies, bytes); + data.assoc_info.req_ies = req_ies; data.assoc_info.req_ies_len = bytes; - hexstr2bin(spos, data.assoc_info.req_ies, bytes); spos += bytes * 2; @@ -274,19 +275,19 @@ wpa_driver_wext_event_wireless_custom(void *ctx, char *custom) goto done; bytes /= 2; - data.assoc_info.resp_ies = os_malloc(bytes); - if (data.assoc_info.resp_ies == NULL) + resp_ies = os_malloc(bytes); + if (resp_ies == NULL) goto done; - + hexstr2bin(spos, resp_ies, bytes); + data.assoc_info.resp_ies = resp_ies; data.assoc_info.resp_ies_len = bytes; - hexstr2bin(spos, data.assoc_info.resp_ies, bytes); } wpa_supplicant_event(ctx, EVENT_ASSOCINFO, &data); done: - os_free(data.assoc_info.resp_ies); - os_free(data.assoc_info.req_ies); + os_free(resp_ies); + os_free(req_ies); #ifdef CONFIG_PEERKEY } else if (os_strncmp(custom, "STKSTART.request=", 17) == 0) { if (hwaddr_aton(custom + 17, data.stkstart.peer)) { @@ -402,19 +403,19 @@ static void wpa_driver_wext_event_assoc_ies(struct wpa_driver_wext_data *drv) os_memset(&data, 0, sizeof(data)); if (drv->assoc_req_ies) { data.assoc_info.req_ies = drv->assoc_req_ies; - drv->assoc_req_ies = NULL; data.assoc_info.req_ies_len = drv->assoc_req_ies_len; } if (drv->assoc_resp_ies) { data.assoc_info.resp_ies = drv->assoc_resp_ies; - drv->assoc_resp_ies = NULL; data.assoc_info.resp_ies_len = drv->assoc_resp_ies_len; } wpa_supplicant_event(drv->ctx, EVENT_ASSOCINFO, &data); - os_free(data.assoc_info.req_ies); - os_free(data.assoc_info.resp_ies); + os_free(drv->assoc_req_ies); + drv->assoc_req_ies = NULL; + os_free(drv->assoc_resp_ies); + drv->assoc_resp_ies = NULL; } diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 050ca1eba..9fcfcbabd 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -27,6 +27,7 @@ #include "rsn_supp/pmksa_cache.h" #include "common/wpa_ctrl.h" #include "eap_peer/eap.h" +#include "ap/hostapd.h" #include "notify.h" #include "common/ieee802_11_defs.h" #include "blacklist.h" @@ -1009,10 +1010,21 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { u8 bssid[ETH_ALEN]; - int ft_completed = wpa_ft_is_completed(wpa_s->wpa); + int ft_completed; int bssid_changed; struct wpa_driver_capa capa; +#ifdef CONFIG_AP + if (wpa_s->ap_iface) { + hostapd_notif_assoc(wpa_s->ap_iface->bss[0], + data->assoc_info.addr, + data->assoc_info.req_ies, + data->assoc_info.req_ies_len); + return; + } +#endif /* CONFIG_AP */ + + ft_completed = wpa_ft_is_completed(wpa_s->wpa); if (data) wpa_supplicant_event_associnfo(wpa_s, data); @@ -1425,10 +1437,24 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, wpa_supplicant_event_assoc(wpa_s, data); break; case EVENT_DISASSOC: +#ifdef CONFIG_AP + if (wpa_s->ap_iface && data) { + hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], + data->disassoc_info.addr); + break; + } +#endif /* CONFIG_AP */ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) sme_event_disassoc(wpa_s, data); /* fall through */ case EVENT_DEAUTH: +#ifdef CONFIG_AP + if (wpa_s->ap_iface && data) { + hostapd_notif_disassoc(wpa_s->ap_iface->bss[0], + data->deauth_info.addr); + break; + } +#endif /* CONFIG_AP */ wpa_supplicant_event_disassoc(wpa_s); break; case EVENT_MICHAEL_MIC_FAILURE: