From 9f324b61babe2fb2a80544a8739eee065e73cd7b Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 9 Apr 2009 19:57:20 +0300 Subject: [PATCH] Share management frame send driver op for hostapd and wpa_supplicant The same implementation can be shared in most cases, so better share the same driver_ops handler function. --- hostapd/driver_i.h | 4 +- src/drivers/driver.h | 1 - src/drivers/driver_hostap.c | 23 +++++----- src/drivers/driver_ndis.c | 1 - src/drivers/driver_nl80211.c | 96 +++++++----------------------------------- src/drivers/driver_privsep.c | 1 - src/drivers/driver_test.c | 5 +-- 7 files changed, 30 insertions(+), 101 deletions(-) diff --git a/hostapd/driver_i.h b/hostapd/driver_i.h index 170c3b3..6594ceb 100644 --- a/hostapd/driver_i.h +++ b/hostapd/driver_i.h @@ -177,9 +177,9 @@ hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len) static inline int hostapd_send_mgmt_frame(struct hostapd_data *hapd, const void *msg, size_t len) { - if (hapd->driver == NULL || hapd->driver->send_mgmt_frame == NULL) + if (hapd->driver == NULL || hapd->driver->send_mlme == NULL) return 0; - return hapd->driver->send_mgmt_frame(hapd->drv_priv, msg, len); + return hapd->driver->send_mlme(hapd->drv_priv, msg, len); } static inline int diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 5242748..32fa495 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1249,7 +1249,6 @@ struct wpa_driver_ops { int (*hapd_set_ssid)(const char *ifname, void *priv, const u8 *buf, int len); int (*hapd_set_countermeasures)(void *priv, int enabled); - int (*send_mgmt_frame)(void *priv, const void *msg, size_t len); int (*sta_add)(const char *ifname, void *priv, struct hostapd_sta_add_params *params); int (*get_inact_sec)(void *priv, const u8 *addr); diff --git a/src/drivers/driver_hostap.c b/src/drivers/driver_hostap.c index e22739d..80d2b61 100644 --- a/src/drivers/driver_hostap.c +++ b/src/drivers/driver_hostap.c @@ -293,7 +293,7 @@ static int hostap_init_sockets(struct hostap_driver_data *drv) } -static int hostap_send_mgmt_frame(void *priv, const void *msg, size_t len) +static int hostap_send_mlme(void *priv, const u8 *msg, size_t len) { struct hostap_driver_data *drv = priv; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) msg; @@ -341,14 +341,13 @@ static int hostap_send_eapol(void *priv, const u8 *addr, const u8 *data, pos += 2; memcpy(pos, data, data_len); - res = hostap_send_mgmt_frame(drv, (u8 *) hdr, len); - free(hdr); - + res = hostap_send_mlme(drv, (u8 *) hdr, len); if (res < 0) { - perror("hostapd_send_eapol: send"); - printf("hostapd_send_eapol - packet len: %lu - failed\n", - (unsigned long) len); + wpa_printf(MSG_ERROR, "hostap_send_eapol - packet len: %lu - " + "failed: %d (%s)", + (unsigned long) len, errno, strerror(errno)); } + free(hdr); return res; } @@ -1145,8 +1144,8 @@ static int hostap_sta_deauth(void *priv, const u8 *addr, int reason) memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN); memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN); mgmt.u.deauth.reason_code = host_to_le16(reason); - return hostap_send_mgmt_frame(drv, &mgmt, IEEE80211_HDRLEN + - sizeof(mgmt.u.deauth)); + return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN + + sizeof(mgmt.u.deauth)); } @@ -1162,8 +1161,8 @@ static int hostap_sta_disassoc(void *priv, const u8 *addr, int reason) memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN); memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN); mgmt.u.disassoc.reason_code = host_to_le16(reason); - return hostap_send_mgmt_frame(drv, &mgmt, IEEE80211_HDRLEN + - sizeof(mgmt.u.disassoc)); + return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN + + sizeof(mgmt.u.disassoc)); } @@ -1711,7 +1710,7 @@ const struct wpa_driver_ops wpa_driver_hostap_ops = { .sta_disassoc = hostap_sta_disassoc, .sta_remove = hostap_sta_remove, .hapd_set_ssid = hostap_set_ssid, - .send_mgmt_frame = hostap_send_mgmt_frame, + .send_mlme = hostap_send_mlme, .sta_add = hostap_sta_add, .get_inact_sec = hostap_get_inact_sec, .sta_clear_stats = hostap_sta_clear_stats, diff --git a/src/drivers/driver_ndis.c b/src/drivers/driver_ndis.c index 875aa25..25cf0ba 100644 --- a/src/drivers/driver_ndis.c +++ b/src/drivers/driver_ndis.c @@ -3233,7 +3233,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = { NULL /* hapd_get_ssid */, NULL /* hapd_set_ssid */, NULL /* hapd_set_countermeasures */, - NULL /* send_mgmt_frame */, NULL /* sta_add */, NULL /* get_inact_sec */, NULL /* sta_clear_stats */, diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index f5f18c0..2372d7a 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -1960,10 +1960,6 @@ wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags) return NULL; } -#endif /* CONFIG_AP || HOSTAPD */ - - -#ifdef CONFIG_AP static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv, const void *data, size_t len, @@ -2035,6 +2031,10 @@ static int wpa_driver_nl80211_send_mlme(void *priv, const u8 *data, !do_not_encrypt); } +#endif /* CONFIG_AP || HOSTAPD */ + + +#ifdef CONFIG_AP static int wpa_driver_nl80211_set_beacon(void *priv, const u8 *head, size_t head_len, @@ -3038,72 +3038,6 @@ static int i802_set_rate_sets(void *priv, int *supp_rates, int *basic_rates, } -static int i802_send_frame(void *priv, const void *data, size_t len, - int encrypt) -{ - __u8 rtap_hdr[] = { - 0x00, 0x00, /* radiotap version */ - 0x0e, 0x00, /* radiotap length */ - 0x02, 0xc0, 0x00, 0x00, /* bmap: flags, tx and rx flags */ - IEEE80211_RADIOTAP_F_FRAG, /* F_FRAG (fragment if required) */ - 0x00, /* padding */ - 0x00, 0x00, /* RX and TX flags to indicate that */ - 0x00, 0x00, /* this is the injected frame directly */ - }; - struct wpa_driver_nl80211_data *drv = priv; - struct iovec iov[2] = { - { - .iov_base = &rtap_hdr, - .iov_len = sizeof(rtap_hdr), - }, - { - .iov_base = (void*)data, - .iov_len = len, - } - }; - struct msghdr msg = { - .msg_name = NULL, - .msg_namelen = 0, - .msg_iov = iov, - .msg_iovlen = 2, - .msg_control = NULL, - .msg_controllen = 0, - .msg_flags = 0, - }; - - if (encrypt) - rtap_hdr[8] |= IEEE80211_RADIOTAP_F_WEP; - - return sendmsg(drv->monitor_sock, &msg, 0); -} - -static int i802_send_mgmt_frame(void *priv, const void *data, size_t len) -{ - struct ieee80211_mgmt *mgmt; - int do_not_encrypt = 0; - u16 fc; - - mgmt = (struct ieee80211_mgmt *) data; - fc = le_to_host16(mgmt->frame_control); - - if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && - WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_AUTH) { - /* - * Only one of the authentication frame types is encrypted. - * In order for static WEP encryption to work properly (i.e., - * to not encrypt the frame), we need to tell mac80211 about - * the frames that must not be encrypted. - */ - u16 auth_alg = le_to_host16(mgmt->u.auth.auth_alg); - u16 auth_trans = le_to_host16(mgmt->u.auth.auth_transaction); - if (auth_alg == WLAN_AUTH_OPEN || - (auth_alg == WLAN_AUTH_SHARED_KEY && auth_trans != 3)) - do_not_encrypt = 1; - } - - return i802_send_frame(priv, data, len, !do_not_encrypt); -} - /* Set kernel driver on given frequency (MHz) */ static int i802_set_freq(void *priv, struct hostapd_freq_params *freq) { @@ -3363,14 +3297,13 @@ static int i802_send_eapol(void *priv, const u8 *addr, const u8 *data, pos += 2; memcpy(pos, data, data_len); - res = i802_send_frame(drv, (u8 *) hdr, len, encrypt); - free(hdr); - + res = wpa_driver_nl80211_send_frame(drv, (u8 *) hdr, len, encrypt); if (res < 0) { - perror("i802_send_eapol: send"); - printf("i802_send_eapol - packet len: %lu - failed\n", - (unsigned long) len); + wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - " + "failed: %d (%s)", + (unsigned long) len, errno, strerror(errno)); } + free(hdr); return res; } @@ -4943,8 +4876,9 @@ static int i802_sta_deauth(void *priv, const u8 *addr, int reason) memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN); memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN); mgmt.u.deauth.reason_code = host_to_le16(reason); - return i802_send_mgmt_frame(drv, &mgmt, IEEE80211_HDRLEN + - sizeof(mgmt.u.deauth)); + return wpa_driver_nl80211_send_mlme(drv, (u8 *) &mgmt, + IEEE80211_HDRLEN + + sizeof(mgmt.u.deauth)); } @@ -4960,8 +4894,9 @@ static int i802_sta_disassoc(void *priv, const u8 *addr, int reason) memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN); memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN); mgmt.u.disassoc.reason_code = host_to_le16(reason); - return i802_send_mgmt_frame(drv, &mgmt, IEEE80211_HDRLEN + - sizeof(mgmt.u.disassoc)); + return wpa_driver_nl80211_send_mlme(drv, (u8 *) &mgmt, + IEEE80211_HDRLEN + + sizeof(mgmt.u.disassoc)); } @@ -5109,7 +5044,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .sta_deauth = i802_sta_deauth, .sta_disassoc = i802_sta_disassoc, .sta_remove = i802_sta_remove, - .send_mgmt_frame = i802_send_mgmt_frame, .sta_add = i802_sta_add, .get_inact_sec = i802_get_inact_sec, .sta_clear_stats = i802_sta_clear_stats, diff --git a/src/drivers/driver_privsep.c b/src/drivers/driver_privsep.c index 7ffd281..fcc0d8e 100644 --- a/src/drivers/driver_privsep.c +++ b/src/drivers/driver_privsep.c @@ -829,7 +829,6 @@ struct wpa_driver_ops wpa_driver_privsep_ops = { NULL /* hapd_get_ssid */, NULL /* hapd_set_ssid */, NULL /* hapd_set_countermeasures */, - NULL /* send_mgmt_frame */, NULL /* sta_add */, NULL /* get_inact_sec */, NULL /* sta_clear_stats */, diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index ab522fc..cc7b166 100644 --- a/src/drivers/driver_test.c +++ b/src/drivers/driver_test.c @@ -297,7 +297,7 @@ static int test_driver_send_ether(void *priv, const u8 *dst, const u8 *src, } -static int test_driver_send_mgmt_frame(void *priv, const void *buf, size_t len) +static int wpa_driver_test_send_mlme(void *priv, const u8 *buf, size_t len) { struct test_driver_data *drv = priv; struct msghdr msg; @@ -2443,7 +2443,7 @@ const struct wpa_driver_ops wpa_driver_test_ops = { .hapd_init = test_driver_init, .hapd_deinit = test_driver_deinit, .hapd_send_eapol = test_driver_send_eapol, - .send_mgmt_frame = test_driver_send_mgmt_frame, + .send_mlme = wpa_driver_test_send_mlme, .set_generic_elem = test_driver_set_generic_elem, .sta_deauth = test_driver_sta_deauth, .sta_disassoc = test_driver_sta_disassoc, @@ -2537,7 +2537,6 @@ const struct wpa_driver_ops wpa_driver_test_ops = { NULL /* hapd_get_ssid */, NULL /* hapd_set_ssid */, NULL /* hapd_set_countermeasures */, - NULL /* send_mgmt_frame */, NULL /* sta_add */, NULL /* get_inact_sec */, NULL /* sta_clear_stats */, -- 1.7.9.5