diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ap/sta_info.c | 2 | ||||
| -rw-r--r-- | src/common/ieee802_11_defs.h | 2 | ||||
| -rw-r--r-- | src/drivers/driver.h | 2 | ||||
| -rw-r--r-- | src/drivers/driver_nl80211.c | 98 | ||||
| -rw-r--r-- | src/p2p/p2p.c | 11 | ||||
| -rw-r--r-- | src/p2p/p2p.h | 15 | ||||
| -rw-r--r-- | src/p2p/p2p_go_neg.c | 30 | ||||
| -rw-r--r-- | src/p2p/p2p_i.h | 1 | ||||
| -rw-r--r-- | src/p2p/p2p_invitation.c | 2 | ||||
| -rw-r--r-- | src/rsn_supp/tdls.c | 2 | ||||
| -rw-r--r-- | src/rsn_supp/wpa_ft.c | 5 | ||||
| -rw-r--r-- | src/tls/libtommath.c | 12 |
12 files changed, 164 insertions, 18 deletions
diff --git a/src/ap/sta_info.c b/src/ap/sta_info.c index 8ada1218..cbafb47f 100644 --- a/src/ap/sta_info.c +++ b/src/ap/sta_info.c @@ -576,7 +576,7 @@ void ap_sta_disassociate(struct hostapd_data *hapd, struct sta_info *sta, { wpa_printf(MSG_DEBUG, "%s: disassociate STA " MACSTR, hapd->conf->iface, MAC2STR(sta->addr)); - sta->flags &= ~WLAN_STA_ASSOC; + sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK); ap_sta_set_authorized(hapd, sta, 0); sta->timeout_next = STA_DEAUTH; wpa_printf(MSG_DEBUG, "%s: reschedule ap_handle_timer timeout " diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 652476ff..f782c865 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -1005,6 +1005,8 @@ enum wifi_display_subelem { /* AKM suite selectors */ #define WLAN_AKM_SUITE_8021X 0x000FAC01 #define WLAN_AKM_SUITE_PSK 0x000FAC02 +#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03 +#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04 #define WLAN_AKM_SUITE_CCKM 0x00409600 diff --git a/src/drivers/driver.h b/src/drivers/driver.h index f12f4bc2..63f90bc0 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -864,6 +864,8 @@ struct wpa_driver_capa { #define WPA_DRIVER_FLAGS_SAE 0x02000000 /* Driver makes use of OBSS scan mechanism in wpa_supplicant */ #define WPA_DRIVER_FLAGS_OBSS_SCAN 0x04000000 +/* Driver supports IBSS (Ad-hoc) mode */ +#define WPA_DRIVER_FLAGS_IBSS 0x08000000 unsigned int flags; int max_scan_ssids; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 3a35a6b5..efd5cab8 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -1642,6 +1642,34 @@ static void mlme_event_remain_on_channel(struct wpa_driver_nl80211_data *drv, } +static void mlme_event_ft_event(struct wpa_driver_nl80211_data *drv, + struct nlattr *tb[]) +{ + union wpa_event_data data; + + os_memset(&data, 0, sizeof(data)); + + if (tb[NL80211_ATTR_IE]) { + data.ft_ies.ies = nla_data(tb[NL80211_ATTR_IE]); + data.ft_ies.ies_len = nla_len(tb[NL80211_ATTR_IE]); + } + + if (tb[NL80211_ATTR_IE_RIC]) { + data.ft_ies.ric_ies = nla_data(tb[NL80211_ATTR_IE_RIC]); + data.ft_ies.ric_ies_len = nla_len(tb[NL80211_ATTR_IE_RIC]); + } + + if (tb[NL80211_ATTR_MAC]) + os_memcpy(data.ft_ies.target_ap, + nla_data(tb[NL80211_ATTR_MAC]), ETH_ALEN); + + wpa_printf(MSG_DEBUG, "nl80211: FT event target_ap " MACSTR, + MAC2STR(data.ft_ies.target_ap)); + + wpa_supplicant_event(drv->ctx, EVENT_FT_RESPONSE, &data); +} + + static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted, struct nlattr *tb[]) { @@ -2232,29 +2260,30 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, switch (cmd) { case NL80211_CMD_TRIGGER_SCAN: - wpa_printf(MSG_DEBUG, "nl80211: Scan trigger"); + wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger"); break; case NL80211_CMD_START_SCHED_SCAN: - wpa_printf(MSG_DEBUG, "nl80211: Sched scan started"); + wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started"); break; case NL80211_CMD_SCHED_SCAN_STOPPED: - wpa_printf(MSG_DEBUG, "nl80211: Sched scan stopped"); + wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped"); wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL); break; case NL80211_CMD_NEW_SCAN_RESULTS: - wpa_printf(MSG_DEBUG, "nl80211: New scan results available"); + wpa_dbg(drv->ctx, MSG_DEBUG, + "nl80211: New scan results available"); drv->scan_complete_events = 1; eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout, drv, drv->ctx); send_scan_event(drv, 0, tb); break; case NL80211_CMD_SCHED_SCAN_RESULTS: - wpa_printf(MSG_DEBUG, - "nl80211: New sched scan results available"); + wpa_dbg(drv->ctx, MSG_DEBUG, + "nl80211: New sched scan results available"); send_scan_event(drv, 0, tb); break; case NL80211_CMD_SCAN_ABORTED: - wpa_printf(MSG_DEBUG, "nl80211: Scan aborted"); + wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan aborted"); /* * Need to indicate that scan results are available in order * not to make wpa_supplicant stop its scanning. @@ -2339,9 +2368,12 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, case NL80211_CMD_CONN_FAILED: nl80211_connect_failed_event(drv, tb); break; + case NL80211_CMD_FT_EVENT: + mlme_event_ft_event(drv, tb); + break; default: - wpa_printf(MSG_DEBUG, "nl80211: Ignored unknown event " - "(cmd=%d)", cmd); + wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Ignored unknown event " + "(cmd=%d)", cmd); break; } } @@ -2569,6 +2601,9 @@ static void wiphy_info_supported_iftypes(struct wiphy_info_data *info, case NL80211_IFTYPE_AP: info->capa->flags |= WPA_DRIVER_FLAGS_AP; break; + case NL80211_IFTYPE_ADHOC: + info->capa->flags |= WPA_DRIVER_FLAGS_IBSS; + break; case NL80211_IFTYPE_P2P_GO: info->p2p_go_supported = 1; break; @@ -3831,6 +3866,7 @@ static int wpa_driver_nl80211_scan(struct i802_bss *bss, int ret = -1, timeout; struct nl_msg *msg, *rates = NULL; + wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: scan request"); drv->scan_for_auth = 0; msg = nl80211_scan_common(drv, NL80211_CMD_TRIGGER_SCAN, params); @@ -3932,6 +3968,8 @@ static int wpa_driver_nl80211_sched_scan(void *priv, struct nl_msg *match_set_rssi = NULL; size_t i; + wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: sched_scan request"); + #ifdef ANDROID if (!drv->capa.sched_scan_supported) return android_pno_start(bss, params); @@ -7173,6 +7211,8 @@ skip_auth_type: if (params->key_mgmt_suite == KEY_MGMT_802_1X || params->key_mgmt_suite == KEY_MGMT_PSK || + params->key_mgmt_suite == KEY_MGMT_FT_802_1X || + params->key_mgmt_suite == KEY_MGMT_FT_PSK || params->key_mgmt_suite == KEY_MGMT_CCKM) { int mgmt = WLAN_AKM_SUITE_PSK; @@ -7183,6 +7223,12 @@ skip_auth_type: case KEY_MGMT_802_1X: mgmt = WLAN_AKM_SUITE_8021X; break; + case KEY_MGMT_FT_802_1X: + mgmt = WLAN_AKM_SUITE_FT_8021X; + break; + case KEY_MGMT_FT_PSK: + mgmt = WLAN_AKM_SUITE_FT_PSK; + break; case KEY_MGMT_PSK: default: mgmt = WLAN_AKM_SUITE_PSK; @@ -9676,6 +9722,39 @@ static int driver_nl80211_probe_req_report(void *priv, int report) } +static int wpa_driver_nl80211_update_ft_ies(void *priv, const u8 *md, + const u8 *ies, size_t ies_len) +{ + int ret; + struct nl_msg *msg; + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + u16 mdid = WPA_GET_LE16(md); + + msg = nlmsg_alloc(); + if (!msg) + return -ENOMEM; + + wpa_printf(MSG_DEBUG, "nl80211: Updating FT IEs"); + nl80211_cmd(drv, msg, 0, NL80211_CMD_UPDATE_FT_IES); + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex); + NLA_PUT(msg, NL80211_ATTR_IE, ies_len, ies); + NLA_PUT_U16(msg, NL80211_ATTR_MDID, mdid); + + ret = send_and_recv_msgs(drv, msg, NULL, NULL); + if (ret) { + wpa_printf(MSG_DEBUG, "nl80211: update_ft_ies failed " + "err=%d (%s)", ret, strerror(-ret)); + } + + return ret; + +nla_put_failure: + nlmsg_free(msg); + return -ENOBUFS; +} + + const struct wpa_driver_ops wpa_driver_nl80211_ops = { .name = "nl80211", .desc = "Linux nl80211/cfg80211", @@ -9751,6 +9830,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .send_tdls_mgmt = nl80211_send_tdls_mgmt, .tdls_oper = nl80211_tdls_oper, #endif /* CONFIG_TDLS */ + .update_ft_ies = wpa_driver_nl80211_update_ft_ies, #ifdef ANDROID_P2P .set_noa = wpa_driver_set_p2p_noa, .get_noa = wpa_driver_get_p2p_noa, diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 704e5310..2b5e5bd1 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -3490,7 +3490,8 @@ static void p2p_timeout_invite_listen(struct p2p_data *p2p) "P2P: Invitation Request retry limit reached"); if (p2p->cfg->invitation_result) p2p->cfg->invitation_result( - p2p->cfg->cb_ctx, -1, NULL, NULL); + p2p->cfg->cb_ctx, -1, NULL, NULL, + p2p->invite_peer->info.p2p_device_addr); } p2p_set_state(p2p, P2P_IDLE); } @@ -4319,6 +4320,14 @@ void p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, } +void p2p_set_own_freq_preference(struct p2p_data *p2p, int freq) +{ + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Own frequency preference: " + "%d MHz", freq); + p2p->own_freq_preference = freq; +} + + const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p) { if (p2p == NULL || p2p->go_neg_peer == NULL) diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 4f9b75d0..28a0a1d1 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -743,6 +743,7 @@ struct p2p_config { * @status: Negotiation result (Status Code) * @bssid: P2P Group BSSID or %NULL if not received * @channels: Available operating channels for the group + * @addr: Peer address * * This callback is used to indicate result of an Invitation procedure * started with a call to p2p_invite(). The indicated status code is @@ -751,7 +752,8 @@ struct p2p_config { * local failure in transmitting the Invitation Request. */ void (*invitation_result)(void *ctx, int status, const u8 *bssid, - const struct p2p_channels *channels); + const struct p2p_channels *channels, + const u8 *addr); /** * go_connected - Check whether we are connected to a GO @@ -1658,6 +1660,17 @@ void p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan); void p2p_set_best_channels(struct p2p_data *p2p, int freq_24, int freq_5, int freq_overall); +/** + * p2p_set_own_freq_preference - Set own preference for channel + * @p2p: P2P module context from p2p_init() + * @freq: Frequency (MHz) of the preferred channel or 0 if no preference + * + * This function can be used to set a preference on the operating channel based + * on frequencies used on the other virtual interfaces that share the same + * radio. If non-zero, this is used to try to avoid multi-channel concurrency. + */ +void p2p_set_own_freq_preference(struct p2p_data *p2p, int freq); + const u8 * p2p_get_go_neg_peer(struct p2p_data *p2p); /** diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index 61153d4f..c143ef4a 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -350,14 +350,36 @@ void p2p_reselect_channel(struct p2p_data *p2p, u8 op_reg_class, op_channel; unsigned int i; - wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Selected operating " - "channel (reg_class %u channel %u) not acceptable to the " - "peer", p2p->op_reg_class, p2p->op_channel); + if (p2p->own_freq_preference > 0 && + p2p_freq_to_channel(p2p->cfg->country, p2p->own_freq_preference, + &op_reg_class, &op_channel) == 0 && + p2p_channels_includes(intersection, op_reg_class, op_channel)) { + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick own channel " + "preference (reg_class %u channel %u) from " + "intersection", op_reg_class, op_channel); + p2p->op_reg_class = op_reg_class; + p2p->op_channel = op_channel; + return; + } + + if (p2p->best_freq_overall > 0 && + p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_overall, + &op_reg_class, &op_channel) == 0 && + p2p_channels_includes(intersection, op_reg_class, op_channel)) { + wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Pick best overall " + "channel (reg_class %u channel %u) from intersection", + op_reg_class, op_channel); + p2p->op_reg_class = op_reg_class; + p2p->op_channel = op_channel; + return; + } /* First, try to pick the best channel from another band */ freq = p2p_channel_to_freq(p2p->cfg->country, p2p->op_reg_class, p2p->op_channel); if (freq >= 2400 && freq < 2500 && p2p->best_freq_5 > 0 && + !p2p_channels_includes(intersection, p2p->op_reg_class, + p2p->op_channel) && p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_5, &op_reg_class, &op_channel) == 0 && p2p_channels_includes(intersection, op_reg_class, op_channel)) { @@ -370,6 +392,8 @@ void p2p_reselect_channel(struct p2p_data *p2p, } if (freq >= 4900 && freq < 6000 && p2p->best_freq_24 > 0 && + !p2p_channels_includes(intersection, p2p->op_reg_class, + p2p->op_channel) && p2p_freq_to_channel(p2p->cfg->country, p2p->best_freq_24, &op_reg_class, &op_channel) == 0 && p2p_channels_includes(intersection, op_reg_class, op_channel)) { diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 5286b020..d5ce52f8 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -430,6 +430,7 @@ struct p2p_data { int best_freq_24; int best_freq_5; int best_freq_overall; + int own_freq_preference; /** * wps_vendor_ext - WPS Vendor Extensions to add diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c index 43d9475d..2ed9730e 100644 --- a/src/p2p/p2p_invitation.c +++ b/src/p2p/p2p_invitation.c @@ -466,7 +466,7 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa, if (p2p->cfg->invitation_result) p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status, - msg.group_bssid, channels); + msg.group_bssid, channels, sa); p2p_parse_free(&msg); diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 09abdbbc..bcd924c9 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -1636,7 +1636,7 @@ skip_rsn: MACSTR " (terminate previously " "initiated negotiation", MAC2STR(src_addr)); - wpa_tdls_peer_free(sm, peer); + wpa_tdls_disable_link(sm, peer->addr); } } } diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 2df060ca..4b08a624 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -788,9 +788,12 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, if (parse.ric) { wpa_hexdump(MSG_MSGDUMP, "FT: RIC Response", parse.ric, parse.ric_len); - /* TODO: parse response and inform driver about results */ + /* TODO: parse response and inform driver about results when + * using wpa_supplicant SME */ } + wpa_printf(MSG_DEBUG, "FT: Completed successfully"); + return 0; } diff --git a/src/tls/libtommath.c b/src/tls/libtommath.c index 741b442c..3fb8fbed 100644 --- a/src/tls/libtommath.c +++ b/src/tls/libtommath.c @@ -42,6 +42,9 @@ /* Include faster sqr at the cost of about 0.5 kB in code */ #define BN_FAST_S_MP_SQR_C +/* About 0.25 kB of code, but ~1.7kB of stack space! */ +#define BN_FAST_S_MP_MUL_DIGS_C + #else /* LTM_FAST */ #define BN_MP_DIV_SMALL @@ -139,7 +142,9 @@ static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); static int s_mp_sqr(mp_int * a, mp_int * b); static int s_mp_mul_high_digs(mp_int * a, mp_int * b, mp_int * c, int digs); +#ifdef BN_FAST_S_MP_MUL_DIGS_C static int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); +#endif #ifdef BN_MP_INIT_MULTI_C static int mp_init_multi(mp_int *mp, ...); @@ -671,6 +676,9 @@ static int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) #ifdef BN_MP_EXPTMOD_FAST_C } #endif + if (dr == 0) { + /* avoid compiler warnings about possibly unused variable */ + } } @@ -2339,12 +2347,14 @@ static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) mp_word r; mp_digit tmpx, *tmpt, *tmpy; +#ifdef BN_FAST_S_MP_MUL_DIGS_C /* can we use the fast multiplier? */ if (((digs) < MP_WARRAY) && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { return fast_s_mp_mul_digs (a, b, c, digs); } +#endif if ((res = mp_init_size (&t, digs)) != MP_OKAY) { return res; @@ -2397,6 +2407,7 @@ static int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) } +#ifdef BN_FAST_S_MP_MUL_DIGS_C /* Fast (comba) multiplier * * This is the fast column-array [comba] multiplier. It is @@ -2482,6 +2493,7 @@ static int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs) mp_clamp (c); return MP_OKAY; } +#endif /* BN_FAST_S_MP_MUL_DIGS_C */ /* init an mp_init for a given size */ |
