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;
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 */
* 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,
* 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,
* 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
* 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
* 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 */
* 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
*/
struct michael_mic_failure {
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 */
#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;
/*
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
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);
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;
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");
wwh->type);
break;
}
- os_free(data.assoc_info.resp_ies);
}
static void * wpa_driver_broadcom_init(void *ctx, const char *ifname)
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;
ielen += 2;
no_ie:
- return hostapd_notif_assoc(hapd, addr, iebuf, ielen);
+ drv_event_assoc(hapd, addr, iebuf, ielen);
}
static void
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
#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;
/*
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
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);
void *ctx, char *custom)
{
union wpa_event_data data;
+ u8 *req_ies = NULL, *resp_ies = NULL;
wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
*/
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;
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);
}
}
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);
}
if (!cli)
return;
-#ifdef HOSTAPD
- hostapd_notif_disassoc(drv->ctx, cli->addr);
-#endif /* HOSTAPD */
+ drv_event_disassoc(drv->ctx, cli->addr);
}
} else if (os_strncmp(custom, "ASSOCINFO(ReqIEs=", 17) == 0) {
char *spos;
int bytes;
+ u8 *req_ies = NULL, *resp_ies = NULL;
spos = custom + 17;
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;
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)) {
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;
}
#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"
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);
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: