aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/events.c
diff options
context:
space:
mode:
authorAntonio Quartulli <antonio@open-mesh.com>2013-07-21 12:56:53 (GMT)
committerJouni Malinen <j@w1.fi>2013-07-21 12:56:53 (GMT)
commit13adc57b39091dc59372efbeb614b74310dd2e02 (patch)
tree2df0695b7fb6c9c8d068b488de396c8739f737fb /wpa_supplicant/events.c
parentb21990b4bbe4e5668cfe87228730420628b6de19 (diff)
downloadhostap-13adc57b39091dc59372efbeb614b74310dd2e02.zip
hostap-13adc57b39091dc59372efbeb614b74310dd2e02.tar.gz
hostap-13adc57b39091dc59372efbeb614b74310dd2e02.tar.bz2
IBSS RSN: Add peer restart detection
To better support the IBSS/RSN mechanism, wpa_supplicant has to be able to detect a possible peer reboot and in this case it should start a new EAPOL handshake. To perform such reboot detection wpa_supplicant has to perform an Open Authentication by sending an Authentication frame and then replying to it. IF an Authentication frame is received when the key have already been exchanged, wpa_supplicant understands that the peer has rebooted and can reset its state machine. Whenever a new peer is added to the IBSS wpa_supplicant will start the Open Authentication and only after having accomplished it will start the key exchange. If the driver does not support Authentication frame exchange initiated from user space, this step is skipped to maintain previous behavior (just go through EAPOL-Key frame processing). The Open Authentication was partly supported by the Linux kernel but now wpa_supplicant can register for Authentication frames, handle it in userspace and so avoid any possible race condition. Signed-hostap: Nicolas Cavallari <cavallar@lri.fr> Signed-hostap: Antonio Quartulli <antonio@open-mesh.com>
Diffstat (limited to 'wpa_supplicant/events.c')
-rw-r--r--wpa_supplicant/events.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index fcd0f79..5aae8cd 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2330,6 +2330,23 @@ static void wpa_supplicant_event_ibss_rsn_start(struct wpa_supplicant *wpa_s,
ibss_rsn_start(wpa_s->ibss_rsn, data->ibss_rsn_start.peer);
}
+
+
+static void wpa_supplicant_event_ibss_auth(struct wpa_supplicant *wpa_s,
+ union wpa_event_data *data)
+{
+ struct wpa_ssid *ssid = wpa_s->current_ssid;
+
+ if (ssid == NULL)
+ return;
+
+ /* check if the ssid is correctly configured as IBSS/RSN */
+ if (ssid->mode != WPAS_MODE_IBSS || !wpa_key_mgmt_wpa(ssid->key_mgmt))
+ return;
+
+ ibss_rsn_handle_auth(wpa_s->ibss_rsn, data->rx_mgmt.frame,
+ data->rx_mgmt.frame_len);
+}
#endif /* CONFIG_IBSS_RSN */
@@ -2724,6 +2741,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
data->ch_switch.ch_offset);
#endif /* CONFIG_AP */
break;
+#endif /* CONFIG_AP */
+#if defined(CONFIG_AP) || defined(CONFIG_IBSS_RSN)
case EVENT_RX_MGMT: {
u16 fc, stype;
const struct ieee80211_mgmt *mgmt;
@@ -2733,7 +2752,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
fc = le_to_host16(mgmt->frame_control);
stype = WLAN_FC_GET_STYPE(fc);
+#ifdef CONFIG_AP
if (wpa_s->ap_iface == NULL) {
+#endif /* CONFIG_AP */
#ifdef CONFIG_P2P
if (stype == WLAN_FC_STYPE_PROBE_REQ &&
data->rx_mgmt.frame_len > 24) {
@@ -2749,9 +2770,17 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break;
}
#endif /* CONFIG_P2P */
+#ifdef CONFIG_IBSS_RSN
+ if (stype == WLAN_FC_STYPE_AUTH &&
+ data->rx_mgmt.frame_len >= 30) {
+ wpa_supplicant_event_ibss_auth(wpa_s, data);
+ break;
+ }
+#endif /* CONFIG_IBSS_RSN */
wpa_dbg(wpa_s, MSG_DEBUG, "AP: ignore received "
"management frame in non-AP mode");
break;
+#ifdef CONFIG_AP
}
if (stype == WLAN_FC_STYPE_PROBE_REQ &&
@@ -2767,9 +2796,10 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
}
ap_mgmt_rx(wpa_s, &data->rx_mgmt);
+#endif /* CONFIG_AP */
break;
}
-#endif /* CONFIG_AP */
+#endif /* CONFIG_AP || CONFIG_IBSS_RSN */
case EVENT_RX_ACTION:
wpa_dbg(wpa_s, MSG_DEBUG, "Received Action frame: SA=" MACSTR
" Category=%u DataLen=%d freq=%d MHz",