TDLS: Add initial support for TDLS (IEEE Std 802.11z-2010)
This commit is contained in:
parent
23ab8e863f
commit
281ff0aa76
17 changed files with 2036 additions and 5 deletions
|
@ -101,6 +101,11 @@
|
|||
/* Status codes (IEEE 802.11-2007, 7.3.1.9, Table 7-23) */
|
||||
#define WLAN_STATUS_SUCCESS 0
|
||||
#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
|
||||
#define WLAN_STATUS_TDLS_WAKEUP_ALTERNATE 2
|
||||
#define WLAN_STATUS_TDLS_WAKEUP_REJECT 3
|
||||
#define WLAN_STATUS_SECURITY_DISABLED 5
|
||||
#define WLAN_STATUS_UNACCEPTABLE_LIFETIME 6
|
||||
#define WLAN_STATUS_NOT_IN_SAME_BSS 7
|
||||
#define WLAN_STATUS_CAPS_UNSUPPORTED 10
|
||||
#define WLAN_STATUS_REASSOC_NO_ASSOC 11
|
||||
#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
|
||||
|
@ -148,6 +153,7 @@
|
|||
#define WLAN_STATUS_INVALID_PMKID 53
|
||||
#define WLAN_STATUS_INVALID_MDIE 54
|
||||
#define WLAN_STATUS_INVALID_FTIE 55
|
||||
#define WLAN_STATUS_INVALID_RSNIE 72
|
||||
|
||||
/* Reason codes (IEEE 802.11-2007, 7.3.1.7, Table 7-22) */
|
||||
#define WLAN_REASON_UNSPECIFIED 1
|
||||
|
@ -175,6 +181,8 @@
|
|||
#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22
|
||||
#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23
|
||||
#define WLAN_REASON_CIPHER_SUITE_REJECTED 24
|
||||
#define WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE 25
|
||||
#define WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED 26
|
||||
/* IEEE 802.11e */
|
||||
#define WLAN_REASON_DISASSOC_LOW_ACK 34
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#endif /* CONFIG_IEEE80211R */
|
||||
#define RSN_AUTH_KEY_MGMT_802_1X_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
|
||||
#define RSN_AUTH_KEY_MGMT_PSK_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
|
||||
#define RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE RSN_SELECTOR(0x00, 0x0f, 0xac, 7)
|
||||
|
||||
#define RSN_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x0f, 0xac, 0)
|
||||
#define RSN_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
|
||||
|
@ -68,6 +69,7 @@
|
|||
#ifdef CONFIG_IEEE80211W
|
||||
#define RSN_CIPHER_SUITE_AES_128_CMAC RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#define RSN_CIPHER_SUITE_NO_GROUP_ADDRESSED RSN_SELECTOR(0x00, 0x0f, 0xac, 7)
|
||||
|
||||
/* EAPOL-Key Key Data Encapsulation
|
||||
* GroupKey and PeerKey require encryption, otherwise, encryption is optional.
|
||||
|
|
|
@ -694,6 +694,14 @@ struct p2p_params {
|
|||
size_t num_sec_dev_types;
|
||||
};
|
||||
|
||||
enum tdls_oper {
|
||||
TDLS_DISCOVERY_REQ,
|
||||
TDLS_SETUP,
|
||||
TDLS_TEARDOWN,
|
||||
TDLS_ENABLE_LINK,
|
||||
TDLS_DISABLE_LINK
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wpa_driver_ops - Driver interface API definition
|
||||
*
|
||||
|
@ -2187,6 +2195,26 @@ struct wpa_driver_ops {
|
|||
int (*p2p_invite)(void *priv, const u8 *peer, int role,
|
||||
const u8 *bssid, const u8 *ssid, size_t ssid_len,
|
||||
const u8 *go_dev_addr, int persistent_group);
|
||||
|
||||
/**
|
||||
* send_tdls_mgmt - for sending TDLS management packets
|
||||
* @priv: private driver interface data
|
||||
* @dst: Destination (peer) MAC address
|
||||
* @action_code: TDLS action code for the mssage
|
||||
* @dialog_token: Dialog Token to use in the message (if needed)
|
||||
* @status_code: Status Code or Reason Code to use (if needed)
|
||||
* @buf: TDLS IEs to add to the message
|
||||
* @len: Length of buf in octets
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This optional function can be used to send packet to driver which is
|
||||
* responsible for receiving and sending all TDLS packets.
|
||||
*/
|
||||
int (*send_tdls_mgmt)(void *priv, const u8 *dst, u8 action_code,
|
||||
u8 dialog_token, u16 status_code,
|
||||
const u8 *buf, size_t len);
|
||||
|
||||
int (*tdls_oper)(void *priv, enum tdls_oper oper, const u8 *peer);
|
||||
};
|
||||
|
||||
|
||||
|
@ -2308,6 +2336,13 @@ enum wpa_event_type {
|
|||
*/
|
||||
EVENT_STKSTART,
|
||||
|
||||
/**
|
||||
* EVENT_TDLS - Request TDLS operation
|
||||
*
|
||||
* This event can be used to request a TDLS operation to be performed.
|
||||
*/
|
||||
EVENT_TDLS,
|
||||
|
||||
/**
|
||||
* EVENT_FT_RESPONSE - Report FT (IEEE 802.11r) response IEs
|
||||
*
|
||||
|
@ -2757,6 +2792,18 @@ union wpa_event_data {
|
|||
u8 peer[ETH_ALEN];
|
||||
} stkstart;
|
||||
|
||||
/**
|
||||
* struct tdls - Data for EVENT_TDLS
|
||||
*/
|
||||
struct tdls {
|
||||
u8 peer[ETH_ALEN];
|
||||
enum {
|
||||
TDLS_REQUEST_SETUP,
|
||||
TDLS_REQUEST_TEARDOWN
|
||||
} oper;
|
||||
u16 reason_code; /* for teardown */
|
||||
} tdls;
|
||||
|
||||
/**
|
||||
* struct ft_ies - FT information elements (EVENT_FT_RESPONSE)
|
||||
*
|
||||
|
|
|
@ -3324,5 +3324,7 @@ const struct wpa_driver_ops wpa_driver_ndis_ops = {
|
|||
NULL /* p2p_sd_response */,
|
||||
NULL /* p2p_service_update */,
|
||||
NULL /* p2p_reject */,
|
||||
NULL /* p2p_invite */
|
||||
NULL /* p2p_invite */,
|
||||
NULL /* send_tdls_mgmt */,
|
||||
NULL /* tdls_oper */
|
||||
};
|
||||
|
|
1700
src/rsn_supp/tdls.c
Normal file
1700
src/rsn_supp/tdls.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -55,6 +55,12 @@ struct wpa_sm_ctx {
|
|||
int (*send_ft_action)(void *ctx, u8 action, const u8 *target_ap,
|
||||
const u8 *ies, size_t ies_len);
|
||||
int (*mark_authenticated)(void *ctx, const u8 *target_ap);
|
||||
#ifdef CONFIG_TDLS
|
||||
int (*send_tdls_mgmt)(void *ctx, const u8 *dst,
|
||||
u8 action_code, u8 dialog_token,
|
||||
u16 status_code, const u8 *buf, size_t len);
|
||||
int (*tdls_oper)(void *ctx, int oper, const u8 *peer);
|
||||
#endif /* CONFIG_TDLS */
|
||||
};
|
||||
|
||||
|
||||
|
@ -330,4 +336,12 @@ wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
|
|||
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
|
||||
|
||||
/* tdls.c */
|
||||
int wpa_tdls_start(struct wpa_sm *sm, const u8 *addr);
|
||||
int wpa_tdls_recv_teardown_notify(struct wpa_sm *sm, const u8 *addr,
|
||||
u16 reason_code);
|
||||
int wpa_tdls_init(struct wpa_sm *sm);
|
||||
void wpa_tdls_deinit(struct wpa_sm *sm);
|
||||
|
||||
#endif /* WPA_H */
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "utils/list.h"
|
||||
|
||||
struct wpa_peerkey;
|
||||
struct wpa_tdls_peer;
|
||||
struct wpa_eapol_key;
|
||||
|
||||
/**
|
||||
|
@ -43,6 +44,7 @@ struct wpa_sm {
|
|||
|
||||
struct l2_packet_data *l2_preauth;
|
||||
struct l2_packet_data *l2_preauth_br;
|
||||
struct l2_packet_data *l2_tdls;
|
||||
u8 preauth_bssid[ETH_ALEN]; /* current RSN pre-auth peer or
|
||||
* 00:00:00:00:00:00 if no pre-auth is
|
||||
* in progress */
|
||||
|
@ -92,6 +94,9 @@ struct wpa_sm {
|
|||
#ifdef CONFIG_PEERKEY
|
||||
struct wpa_peerkey *peerkey;
|
||||
#endif /* CONFIG_PEERKEY */
|
||||
#ifdef CONFIG_TDLS
|
||||
struct wpa_tdls_peer *tdls;
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
u8 xxkey[PMK_LEN]; /* PSK or the second 256 bits of MSK */
|
||||
|
@ -237,6 +242,27 @@ static inline int wpa_sm_mark_authenticated(struct wpa_sm *sm,
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TDLS
|
||||
static inline int wpa_sm_send_tdls_mgmt(struct wpa_sm *sm, const u8 *dst,
|
||||
u8 action_code, u8 dialog_token,
|
||||
u16 status_code, const u8 *buf,
|
||||
size_t len)
|
||||
{
|
||||
if (sm->ctx->send_tdls_mgmt)
|
||||
return sm->ctx->send_tdls_mgmt(sm->ctx->ctx, dst, action_code,
|
||||
dialog_token, status_code,
|
||||
buf, len);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int wpa_sm_tdls_oper(struct wpa_sm *sm, int oper,
|
||||
const u8 *peer)
|
||||
{
|
||||
if (sm->ctx->tdls_oper)
|
||||
return sm->ctx->tdls_oper(sm->ctx->ctx, oper, peer);
|
||||
return -1;
|
||||
}
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
void wpa_eapol_key_send(struct wpa_sm *sm, const u8 *kck,
|
||||
int ver, const u8 *dest, u16 proto,
|
||||
|
|
|
@ -397,7 +397,6 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
|||
ie->rsn_ie_len = pos[1] + 2;
|
||||
wpa_hexdump(MSG_DEBUG, "WPA: RSN IE in EAPOL-Key",
|
||||
ie->rsn_ie, ie->rsn_ie_len);
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
} else if (*pos == WLAN_EID_MOBILITY_DOMAIN) {
|
||||
ie->mdie = pos;
|
||||
ie->mdie_len = pos[1] + 2;
|
||||
|
@ -424,7 +423,9 @@ int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
|||
"EAPOL-Key Key Data IE",
|
||||
pos, 2 + pos[1]);
|
||||
}
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
} else if (*pos == WLAN_EID_LINK_ID) {
|
||||
ie->lnkid = pos;
|
||||
ie->lnkid_len = pos[1] + 2;
|
||||
} else if (*pos == WLAN_EID_VENDOR_SPECIFIC) {
|
||||
ret = wpa_parse_generic(pos, end, ie);
|
||||
if (ret < 0)
|
||||
|
|
|
@ -41,14 +41,14 @@ struct wpa_eapol_ie_parse {
|
|||
const u8 *igtk;
|
||||
size_t igtk_len;
|
||||
#endif /* CONFIG_IEEE80211W */
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
const u8 *mdie;
|
||||
size_t mdie_len;
|
||||
const u8 *ftie;
|
||||
size_t ftie_len;
|
||||
const u8 *reassoc_deadline;
|
||||
const u8 *key_lifetime;
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
const u8 *lnkid;
|
||||
size_t lnkid_len;
|
||||
};
|
||||
|
||||
int wpa_supplicant_parse_ies(const u8 *buf, size_t len,
|
||||
|
|
|
@ -320,6 +320,9 @@ static inline unsigned int wpa_swap_32(unsigned int v)
|
|||
#ifndef ETH_P_ALL
|
||||
#define ETH_P_ALL 0x0003
|
||||
#endif
|
||||
#ifndef ETH_P_80211_ENCAP
|
||||
#define ETH_P_80211_ENCAP 0x890d /* TDLS comes under this category */
|
||||
#endif
|
||||
#ifndef ETH_P_PAE
|
||||
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
|
||||
#endif /* ETH_P_PAE */
|
||||
|
|
|
@ -142,6 +142,13 @@ NEED_SHA256=y
|
|||
NEED_AES_OMAC1=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_TDLS
|
||||
CFLAGS += -DCONFIG_TDLS
|
||||
OBJS += ../src/rsn_supp/tdls.o
|
||||
NEED_SHA256=y
|
||||
NEED_AES_OMAC1=y
|
||||
endif
|
||||
|
||||
ifdef CONFIG_PEERKEY
|
||||
CFLAGS += -DCONFIG_PEERKEY
|
||||
endif
|
||||
|
|
|
@ -181,6 +181,64 @@ static int wpa_supplicant_ctrl_iface_stkstart(
|
|||
#endif /* CONFIG_PEERKEY */
|
||||
|
||||
|
||||
#ifdef CONFIG_TDLS
|
||||
|
||||
static int wpa_supplicant_ctrl_iface_tdls_discover(
|
||||
struct wpa_supplicant *wpa_s, char *addr)
|
||||
{
|
||||
u8 peer[ETH_ALEN];
|
||||
|
||||
if (hwaddr_aton(addr, peer)) {
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER: invalid "
|
||||
"address '%s'", addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_DISCOVER " MACSTR,
|
||||
MAC2STR(peer));
|
||||
|
||||
return wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_supplicant_ctrl_iface_tdls_setup(
|
||||
struct wpa_supplicant *wpa_s, char *addr)
|
||||
{
|
||||
u8 peer[ETH_ALEN];
|
||||
|
||||
if (hwaddr_aton(addr, peer)) {
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP: invalid "
|
||||
"address '%s'", addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_SETUP " MACSTR,
|
||||
MAC2STR(peer));
|
||||
|
||||
return wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_supplicant_ctrl_iface_tdls_teardown(
|
||||
struct wpa_supplicant *wpa_s, char *addr)
|
||||
{
|
||||
u8 peer[ETH_ALEN];
|
||||
|
||||
if (hwaddr_aton(addr, peer)) {
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN: invalid "
|
||||
"address '%s'", addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "CTRL_IFACE TDLS_TEARDOWN " MACSTR,
|
||||
MAC2STR(peer));
|
||||
|
||||
return wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
static int wpa_supplicant_ctrl_iface_ft_ds(
|
||||
struct wpa_supplicant *wpa_s, char *addr)
|
||||
|
@ -3118,6 +3176,17 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
|||
} else if (os_strncmp(buf, "STA_AUTOCONNECT ", 16) == 0) {
|
||||
if (wpa_supplicant_ctrl_iface_sta_autoconnect(wpa_s, buf + 16))
|
||||
reply_len = -1;
|
||||
#ifdef CONFIG_TDLS
|
||||
} else if (os_strncmp(buf, "TDLS_DISCOVER ", 14) == 0) {
|
||||
if (wpa_supplicant_ctrl_iface_tdls_discover(wpa_s, buf + 14))
|
||||
reply_len = -1;
|
||||
} else if (os_strncmp(buf, "TDLS_SETUP ", 11) == 0) {
|
||||
if (wpa_supplicant_ctrl_iface_tdls_setup(wpa_s, buf + 11))
|
||||
reply_len = -1;
|
||||
} else if (os_strncmp(buf, "TDLS_TEARDOWN ", 14) == 0) {
|
||||
if (wpa_supplicant_ctrl_iface_tdls_teardown(wpa_s, buf + 14))
|
||||
reply_len = -1;
|
||||
#endif /* CONFIG_TDLS */
|
||||
} else {
|
||||
os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
|
||||
reply_len = 16;
|
||||
|
|
|
@ -675,5 +675,25 @@ static inline int wpa_drv_p2p_invite(struct wpa_supplicant *wpa_s,
|
|||
persistent_group);
|
||||
}
|
||||
|
||||
static inline int wpa_drv_send_tdls_mgmt(struct wpa_supplicant *wpa_s,
|
||||
const u8 *dst, u8 action_code,
|
||||
u8 dialog_token, u16 status_code,
|
||||
const u8 *buf, size_t len)
|
||||
{
|
||||
if (wpa_s->driver->send_tdls_mgmt) {
|
||||
return wpa_s->driver->send_tdls_mgmt(wpa_s->drv_priv, dst,
|
||||
action_code, dialog_token,
|
||||
status_code, buf, len);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline int wpa_drv_tdls_oper(struct wpa_supplicant *wpa_s,
|
||||
enum tdls_oper oper, const u8 *peer)
|
||||
{
|
||||
if (!wpa_s->driver->tdls_oper)
|
||||
return -1;
|
||||
return wpa_s->driver->tdls_oper(wpa_s->drv_priv, oper, peer);
|
||||
}
|
||||
|
||||
#endif /* DRIVER_I_H */
|
||||
|
|
|
@ -1587,6 +1587,26 @@ wpa_supplicant_event_stkstart(struct wpa_supplicant *wpa_s,
|
|||
#endif /* CONFIG_PEERKEY */
|
||||
|
||||
|
||||
#ifdef CONFIG_TDLS
|
||||
static void wpa_supplicant_event_tdls(struct wpa_supplicant *wpa_s,
|
||||
union wpa_event_data *data)
|
||||
{
|
||||
if (data == NULL)
|
||||
return;
|
||||
switch (data->tdls.oper) {
|
||||
case TDLS_REQUEST_SETUP:
|
||||
wpa_tdls_start(wpa_s->wpa, data->tdls.peer);
|
||||
break;
|
||||
case TDLS_REQUEST_TEARDOWN:
|
||||
/* request from driver to add FTIE */
|
||||
wpa_tdls_recv_teardown_notify(wpa_s->wpa, data->tdls.peer,
|
||||
data->tdls.reason_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
static void
|
||||
wpa_supplicant_event_ft_response(struct wpa_supplicant *wpa_s,
|
||||
|
@ -1818,6 +1838,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|||
wpa_supplicant_event_stkstart(wpa_s, data);
|
||||
break;
|
||||
#endif /* CONFIG_PEERKEY */
|
||||
#ifdef CONFIG_TDLS
|
||||
case EVENT_TDLS:
|
||||
wpa_supplicant_event_tdls(wpa_s, data);
|
||||
break;
|
||||
#endif /* CONFIG_TDLS */
|
||||
#ifdef CONFIG_IEEE80211R
|
||||
case EVENT_FT_RESPONSE:
|
||||
wpa_supplicant_event_ft_response(wpa_s, data);
|
||||
|
|
|
@ -2153,6 +2153,69 @@ static int wpa_cli_cmd_sta_autoconnect(struct wpa_ctrl *ctrl, int argc,
|
|||
}
|
||||
|
||||
|
||||
static int wpa_cli_cmd_tdls_discover(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char cmd[256];
|
||||
int res;
|
||||
|
||||
if (argc != 1) {
|
||||
printf("Invalid TDLS_DISCOVER command: needs one argument "
|
||||
"(Peer STA MAC address)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = os_snprintf(cmd, sizeof(cmd), "TDLS_DISCOVER %s", argv[0]);
|
||||
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||
printf("Too long TDLS_DISCOVER command.\n");
|
||||
return -1;
|
||||
}
|
||||
return wpa_ctrl_command(ctrl, cmd);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_cli_cmd_tdls_setup(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char cmd[256];
|
||||
int res;
|
||||
|
||||
if (argc != 1) {
|
||||
printf("Invalid TDLS_SETUP command: needs one argument "
|
||||
"(Peer STA MAC address)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = os_snprintf(cmd, sizeof(cmd), "TDLS_SETUP %s", argv[0]);
|
||||
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||
printf("Too long TDLS_SETUP command.\n");
|
||||
return -1;
|
||||
}
|
||||
return wpa_ctrl_command(ctrl, cmd);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_cli_cmd_tdls_teardown(struct wpa_ctrl *ctrl, int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char cmd[256];
|
||||
int res;
|
||||
|
||||
if (argc != 1) {
|
||||
printf("Invalid TDLS_TEARDOWN command: needs one argument "
|
||||
"(Peer STA MAC address)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = os_snprintf(cmd, sizeof(cmd), "TDLS_TEARDOWN %s", argv[0]);
|
||||
if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
|
||||
printf("Too long TDLS_TEARDOWN command.\n");
|
||||
return -1;
|
||||
}
|
||||
return wpa_ctrl_command(ctrl, cmd);
|
||||
}
|
||||
|
||||
|
||||
enum wpa_cli_cmd_flags {
|
||||
cli_cmd_flag_none = 0x00,
|
||||
cli_cmd_flag_sensitive = 0x01
|
||||
|
@ -2450,6 +2513,15 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
|
|||
#endif /* CONFIG_P2P */
|
||||
{ "sta_autoconnect", wpa_cli_cmd_sta_autoconnect, cli_cmd_flag_none,
|
||||
"<0/1> = disable/enable automatic reconnection" },
|
||||
{ "tdls_discover", wpa_cli_cmd_tdls_discover,
|
||||
cli_cmd_flag_none,
|
||||
"<addr> = request TDLS discovery with <addr>" },
|
||||
{ "tdls_setup", wpa_cli_cmd_tdls_setup,
|
||||
cli_cmd_flag_none,
|
||||
"<addr> = request TDLS setup with <addr>" },
|
||||
{ "tdls_teardown", wpa_cli_cmd_tdls_teardown,
|
||||
cli_cmd_flag_none,
|
||||
"<addr> = tear down TDLS with <addr>" },
|
||||
{ NULL, NULL, cli_cmd_flag_none, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -402,6 +402,10 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
|
|||
|
||||
rsn_preauth_deinit(wpa_s->wpa);
|
||||
|
||||
#ifdef CONFIG_TDLS
|
||||
wpa_tdls_deinit(wpa_s->wpa);
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
pmksa_candidate_free(wpa_s->wpa);
|
||||
wpa_sm_deinit(wpa_s->wpa);
|
||||
wpa_s->wpa = NULL;
|
||||
|
@ -2136,6 +2140,11 @@ next_driver:
|
|||
if (wpa_supplicant_driver_init(wpa_s) < 0)
|
||||
return -1;
|
||||
|
||||
#ifdef CONFIG_TDLS
|
||||
if (wpa_tdls_init(wpa_s->wpa))
|
||||
return -1;
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
if (wpa_s->conf->country[0] && wpa_s->conf->country[1] &&
|
||||
wpa_drv_set_country(wpa_s, wpa_s->conf->country)) {
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "Failed to set country");
|
||||
|
|
|
@ -535,6 +535,28 @@ static int wpa_supplicant_mark_authenticated(void *ctx, const u8 *target_ap)
|
|||
#endif /* CONFIG_NO_WPA */
|
||||
|
||||
|
||||
#ifdef CONFIG_TDLS
|
||||
|
||||
static int wpa_supplicant_send_tdls_mgmt(void *ctx, const u8 *dst,
|
||||
u8 action_code, u8 dialog_token,
|
||||
u16 status_code, const u8 *buf,
|
||||
size_t len)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = ctx;
|
||||
return wpa_drv_send_tdls_mgmt(wpa_s, dst, action_code, dialog_token,
|
||||
status_code, buf, len);
|
||||
}
|
||||
|
||||
|
||||
static int wpa_supplicant_tdls_oper(void *ctx, int oper, const u8 *peer)
|
||||
{
|
||||
struct wpa_supplicant *wpa_s = ctx;
|
||||
return wpa_drv_tdls_oper(wpa_s, oper, peer);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
|
||||
#ifdef IEEE8021X_EAPOL
|
||||
#if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
|
||||
static void wpa_supplicant_eap_param_needed(void *ctx, const char *field,
|
||||
|
@ -668,6 +690,10 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
|
|||
ctx->send_ft_action = wpa_supplicant_send_ft_action;
|
||||
ctx->mark_authenticated = wpa_supplicant_mark_authenticated;
|
||||
#endif /* CONFIG_IEEE80211R */
|
||||
#ifdef CONFIG_TDLS
|
||||
ctx->send_tdls_mgmt = wpa_supplicant_send_tdls_mgmt;
|
||||
ctx->tdls_oper = wpa_supplicant_tdls_oper;
|
||||
#endif /* CONFIG_TDLS */
|
||||
|
||||
wpa_s->wpa = wpa_sm_init(ctx);
|
||||
if (wpa_s->wpa == NULL) {
|
||||
|
|
Loading…
Reference in a new issue