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.
This commit is contained in:
parent
8342130269
commit
9f324b61ba
7 changed files with 30 additions and 101 deletions
|
@ -177,9 +177,9 @@ hostapd_set_ssid(struct hostapd_data *hapd, const u8 *buf, size_t len)
|
||||||
static inline int
|
static inline int
|
||||||
hostapd_send_mgmt_frame(struct hostapd_data *hapd, const void *msg, size_t len)
|
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 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
|
static inline int
|
||||||
|
|
|
@ -1249,7 +1249,6 @@ struct wpa_driver_ops {
|
||||||
int (*hapd_set_ssid)(const char *ifname, void *priv, const u8 *buf,
|
int (*hapd_set_ssid)(const char *ifname, void *priv, const u8 *buf,
|
||||||
int len);
|
int len);
|
||||||
int (*hapd_set_countermeasures)(void *priv, int enabled);
|
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,
|
int (*sta_add)(const char *ifname, void *priv,
|
||||||
struct hostapd_sta_add_params *params);
|
struct hostapd_sta_add_params *params);
|
||||||
int (*get_inact_sec)(void *priv, const u8 *addr);
|
int (*get_inact_sec)(void *priv, const u8 *addr);
|
||||||
|
|
|
@ -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 hostap_driver_data *drv = priv;
|
||||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) msg;
|
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;
|
pos += 2;
|
||||||
memcpy(pos, data, data_len);
|
memcpy(pos, data, data_len);
|
||||||
|
|
||||||
res = hostap_send_mgmt_frame(drv, (u8 *) hdr, len);
|
res = hostap_send_mlme(drv, (u8 *) hdr, len);
|
||||||
free(hdr);
|
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
perror("hostapd_send_eapol: send");
|
wpa_printf(MSG_ERROR, "hostap_send_eapol - packet len: %lu - "
|
||||||
printf("hostapd_send_eapol - packet len: %lu - failed\n",
|
"failed: %d (%s)",
|
||||||
(unsigned long) len);
|
(unsigned long) len, errno, strerror(errno));
|
||||||
}
|
}
|
||||||
|
free(hdr);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -1145,7 +1144,7 @@ static int hostap_sta_deauth(void *priv, const u8 *addr, int reason)
|
||||||
memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);
|
memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);
|
||||||
memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);
|
memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);
|
||||||
mgmt.u.deauth.reason_code = host_to_le16(reason);
|
mgmt.u.deauth.reason_code = host_to_le16(reason);
|
||||||
return hostap_send_mgmt_frame(drv, &mgmt, IEEE80211_HDRLEN +
|
return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN +
|
||||||
sizeof(mgmt.u.deauth));
|
sizeof(mgmt.u.deauth));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1162,7 +1161,7 @@ static int hostap_sta_disassoc(void *priv, const u8 *addr, int reason)
|
||||||
memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);
|
memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);
|
||||||
memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);
|
memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);
|
||||||
mgmt.u.disassoc.reason_code = host_to_le16(reason);
|
mgmt.u.disassoc.reason_code = host_to_le16(reason);
|
||||||
return hostap_send_mgmt_frame(drv, &mgmt, IEEE80211_HDRLEN +
|
return hostap_send_mlme(drv, (u8 *) &mgmt, IEEE80211_HDRLEN +
|
||||||
sizeof(mgmt.u.disassoc));
|
sizeof(mgmt.u.disassoc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1711,7 +1710,7 @@ const struct wpa_driver_ops wpa_driver_hostap_ops = {
|
||||||
.sta_disassoc = hostap_sta_disassoc,
|
.sta_disassoc = hostap_sta_disassoc,
|
||||||
.sta_remove = hostap_sta_remove,
|
.sta_remove = hostap_sta_remove,
|
||||||
.hapd_set_ssid = hostap_set_ssid,
|
.hapd_set_ssid = hostap_set_ssid,
|
||||||
.send_mgmt_frame = hostap_send_mgmt_frame,
|
.send_mlme = hostap_send_mlme,
|
||||||
.sta_add = hostap_sta_add,
|
.sta_add = hostap_sta_add,
|
||||||
.get_inact_sec = hostap_get_inact_sec,
|
.get_inact_sec = hostap_get_inact_sec,
|
||||||
.sta_clear_stats = hostap_sta_clear_stats,
|
.sta_clear_stats = hostap_sta_clear_stats,
|
||||||
|
|
|
@ -3233,7 +3233,6 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
|
||||||
NULL /* hapd_get_ssid */,
|
NULL /* hapd_get_ssid */,
|
||||||
NULL /* hapd_set_ssid */,
|
NULL /* hapd_set_ssid */,
|
||||||
NULL /* hapd_set_countermeasures */,
|
NULL /* hapd_set_countermeasures */,
|
||||||
NULL /* send_mgmt_frame */,
|
|
||||||
NULL /* sta_add */,
|
NULL /* sta_add */,
|
||||||
NULL /* get_inact_sec */,
|
NULL /* get_inact_sec */,
|
||||||
NULL /* sta_clear_stats */,
|
NULL /* sta_clear_stats */,
|
||||||
|
|
|
@ -1960,10 +1960,6 @@ wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_AP || HOSTAPD */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_AP
|
|
||||||
|
|
||||||
static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv,
|
static int wpa_driver_nl80211_send_frame(struct wpa_driver_nl80211_data *drv,
|
||||||
const void *data, size_t len,
|
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);
|
!do_not_encrypt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_AP || HOSTAPD */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CONFIG_AP
|
||||||
|
|
||||||
static int wpa_driver_nl80211_set_beacon(void *priv,
|
static int wpa_driver_nl80211_set_beacon(void *priv,
|
||||||
const u8 *head, size_t head_len,
|
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) */
|
/* Set kernel driver on given frequency (MHz) */
|
||||||
static int i802_set_freq(void *priv, struct hostapd_freq_params *freq)
|
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;
|
pos += 2;
|
||||||
memcpy(pos, data, data_len);
|
memcpy(pos, data, data_len);
|
||||||
|
|
||||||
res = i802_send_frame(drv, (u8 *) hdr, len, encrypt);
|
res = wpa_driver_nl80211_send_frame(drv, (u8 *) hdr, len, encrypt);
|
||||||
free(hdr);
|
|
||||||
|
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
perror("i802_send_eapol: send");
|
wpa_printf(MSG_ERROR, "i802_send_eapol - packet len: %lu - "
|
||||||
printf("i802_send_eapol - packet len: %lu - failed\n",
|
"failed: %d (%s)",
|
||||||
(unsigned long) len);
|
(unsigned long) len, errno, strerror(errno));
|
||||||
}
|
}
|
||||||
|
free(hdr);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -4943,7 +4876,8 @@ static int i802_sta_deauth(void *priv, const u8 *addr, int reason)
|
||||||
memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);
|
memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);
|
||||||
memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);
|
memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);
|
||||||
mgmt.u.deauth.reason_code = host_to_le16(reason);
|
mgmt.u.deauth.reason_code = host_to_le16(reason);
|
||||||
return i802_send_mgmt_frame(drv, &mgmt, IEEE80211_HDRLEN +
|
return wpa_driver_nl80211_send_mlme(drv, (u8 *) &mgmt,
|
||||||
|
IEEE80211_HDRLEN +
|
||||||
sizeof(mgmt.u.deauth));
|
sizeof(mgmt.u.deauth));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4960,7 +4894,8 @@ static int i802_sta_disassoc(void *priv, const u8 *addr, int reason)
|
||||||
memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);
|
memcpy(mgmt.sa, drv->hapd->own_addr, ETH_ALEN);
|
||||||
memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);
|
memcpy(mgmt.bssid, drv->hapd->own_addr, ETH_ALEN);
|
||||||
mgmt.u.disassoc.reason_code = host_to_le16(reason);
|
mgmt.u.disassoc.reason_code = host_to_le16(reason);
|
||||||
return i802_send_mgmt_frame(drv, &mgmt, IEEE80211_HDRLEN +
|
return wpa_driver_nl80211_send_mlme(drv, (u8 *) &mgmt,
|
||||||
|
IEEE80211_HDRLEN +
|
||||||
sizeof(mgmt.u.disassoc));
|
sizeof(mgmt.u.disassoc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5109,7 +5044,6 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||||
.sta_deauth = i802_sta_deauth,
|
.sta_deauth = i802_sta_deauth,
|
||||||
.sta_disassoc = i802_sta_disassoc,
|
.sta_disassoc = i802_sta_disassoc,
|
||||||
.sta_remove = i802_sta_remove,
|
.sta_remove = i802_sta_remove,
|
||||||
.send_mgmt_frame = i802_send_mgmt_frame,
|
|
||||||
.sta_add = i802_sta_add,
|
.sta_add = i802_sta_add,
|
||||||
.get_inact_sec = i802_get_inact_sec,
|
.get_inact_sec = i802_get_inact_sec,
|
||||||
.sta_clear_stats = i802_sta_clear_stats,
|
.sta_clear_stats = i802_sta_clear_stats,
|
||||||
|
|
|
@ -829,7 +829,6 @@ struct wpa_driver_ops wpa_driver_privsep_ops = {
|
||||||
NULL /* hapd_get_ssid */,
|
NULL /* hapd_get_ssid */,
|
||||||
NULL /* hapd_set_ssid */,
|
NULL /* hapd_set_ssid */,
|
||||||
NULL /* hapd_set_countermeasures */,
|
NULL /* hapd_set_countermeasures */,
|
||||||
NULL /* send_mgmt_frame */,
|
|
||||||
NULL /* sta_add */,
|
NULL /* sta_add */,
|
||||||
NULL /* get_inact_sec */,
|
NULL /* get_inact_sec */,
|
||||||
NULL /* sta_clear_stats */,
|
NULL /* sta_clear_stats */,
|
||||||
|
|
|
@ -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 test_driver_data *drv = priv;
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
|
@ -2443,7 +2443,7 @@ const struct wpa_driver_ops wpa_driver_test_ops = {
|
||||||
.hapd_init = test_driver_init,
|
.hapd_init = test_driver_init,
|
||||||
.hapd_deinit = test_driver_deinit,
|
.hapd_deinit = test_driver_deinit,
|
||||||
.hapd_send_eapol = test_driver_send_eapol,
|
.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,
|
.set_generic_elem = test_driver_set_generic_elem,
|
||||||
.sta_deauth = test_driver_sta_deauth,
|
.sta_deauth = test_driver_sta_deauth,
|
||||||
.sta_disassoc = test_driver_sta_disassoc,
|
.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_get_ssid */,
|
||||||
NULL /* hapd_set_ssid */,
|
NULL /* hapd_set_ssid */,
|
||||||
NULL /* hapd_set_countermeasures */,
|
NULL /* hapd_set_countermeasures */,
|
||||||
NULL /* send_mgmt_frame */,
|
|
||||||
NULL /* sta_add */,
|
NULL /* sta_add */,
|
||||||
NULL /* get_inact_sec */,
|
NULL /* get_inact_sec */,
|
||||||
NULL /* sta_clear_stats */,
|
NULL /* sta_clear_stats */,
|
||||||
|
|
Loading…
Reference in a new issue