wpa_supplicant: Add support to probe mesh link to given peer
Inject an Ethernet frame to a given peer bypassing next_hop lookup in mpath table. Optional payload is expected to be hexdump without 0x. usage: wpa_cli -i <dev> mesh_link_probe <peer MAC> [payload=<hexdump of payload>] example: wpa_cli -i wlan0 mesh_link_probe aa:bb:cc:dd:ee:ff payload=aabb wpa_cli -i wlan0 mesh_link_probe aa:bb:cc:dd:ee:ff Signed-off-by: Pradeep Kumar chitrapu <pradeepc@codeaurora.org>
This commit is contained in:
parent
c36109e4d9
commit
7ace4328c0
3 changed files with 67 additions and 1 deletions
|
@ -8,10 +8,10 @@
|
||||||
|
|
||||||
#include "utils/includes.h"
|
#include "utils/includes.h"
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
#include <net/ethernet.h>
|
|
||||||
#include <netinet/ip.h>
|
#include <netinet/ip.h>
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
|
|
||||||
|
#include <net/ethernet.h>
|
||||||
#include "utils/common.h"
|
#include "utils/common.h"
|
||||||
#include "utils/eloop.h"
|
#include "utils/eloop.h"
|
||||||
#include "utils/uuid.h"
|
#include "utils/uuid.h"
|
||||||
|
@ -3129,6 +3129,49 @@ static int wpa_supplicant_ctrl_iface_mesh_peer_add(
|
||||||
return wpas_mesh_peer_add(wpa_s, addr, duration);
|
return wpas_mesh_peer_add(wpa_s, addr, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_supplicant_ctrl_iface_mesh_link_probe(
|
||||||
|
struct wpa_supplicant *wpa_s, char *cmd)
|
||||||
|
{
|
||||||
|
struct ether_header *eth;
|
||||||
|
u8 addr[ETH_ALEN];
|
||||||
|
u8 *buf;
|
||||||
|
char *pos;
|
||||||
|
size_t payload_len = 0, len;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (hwaddr_aton(cmd, addr))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pos = os_strstr(cmd, " payload=");
|
||||||
|
if (pos) {
|
||||||
|
pos = pos + 9;
|
||||||
|
payload_len = os_strlen(pos);
|
||||||
|
if (payload_len & 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
payload_len /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ETH_HLEN + payload_len;
|
||||||
|
buf = os_malloc(len);
|
||||||
|
if (!buf)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
eth = (struct ether_header *) buf;
|
||||||
|
os_memcpy(eth->ether_dhost, addr, ETH_ALEN);
|
||||||
|
os_memcpy(eth->ether_shost, wpa_s->own_addr, ETH_ALEN);
|
||||||
|
eth->ether_type = htons(ETH_P_802_3);
|
||||||
|
|
||||||
|
if (payload_len && hexstr2bin(pos, buf + ETH_HLEN, payload_len) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ret = wpa_drv_mesh_link_probe(wpa_s, addr, buf, len);
|
||||||
|
fail:
|
||||||
|
os_free(buf);
|
||||||
|
return -ret;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_MESH */
|
#endif /* CONFIG_MESH */
|
||||||
|
|
||||||
|
|
||||||
|
@ -10171,6 +10214,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
} else if (os_strncmp(buf, "MESH_PEER_ADD ", 14) == 0) {
|
} else if (os_strncmp(buf, "MESH_PEER_ADD ", 14) == 0) {
|
||||||
if (wpa_supplicant_ctrl_iface_mesh_peer_add(wpa_s, buf + 14))
|
if (wpa_supplicant_ctrl_iface_mesh_peer_add(wpa_s, buf + 14))
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
|
} else if (os_strncmp(buf, "MESH_LINK_PROBE ", 16) == 0) {
|
||||||
|
if (wpa_supplicant_ctrl_iface_mesh_link_probe(wpa_s, buf + 16))
|
||||||
|
reply_len = -1;
|
||||||
#endif /* CONFIG_MESH */
|
#endif /* CONFIG_MESH */
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
} else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
|
} else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
|
||||||
|
|
|
@ -87,6 +87,16 @@ static inline int wpa_drv_leave_mesh(struct wpa_supplicant *wpa_s)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int wpa_drv_mesh_link_probe(struct wpa_supplicant *wpa_s,
|
||||||
|
const u8 *addr,
|
||||||
|
const u8 *eth, size_t len)
|
||||||
|
{
|
||||||
|
if (wpa_s->driver->probe_mesh_link)
|
||||||
|
return wpa_s->driver->probe_mesh_link(wpa_s->drv_priv, addr,
|
||||||
|
eth, len);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s,
|
static inline int wpa_drv_scan(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_driver_scan_params *params)
|
struct wpa_driver_scan_params *params)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2064,6 +2064,13 @@ static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc,
|
||||||
return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv);
|
return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_cli_cmd_mesh_link_probe(struct wpa_ctrl *ctrl, int argc,
|
||||||
|
char *argv[])
|
||||||
|
{
|
||||||
|
return wpa_cli_cmd(ctrl, "MESH_LINK_PROBE", 1, argc, argv);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_MESH */
|
#endif /* CONFIG_MESH */
|
||||||
|
|
||||||
|
|
||||||
|
@ -3384,6 +3391,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
|
||||||
{ "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
|
{ "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
|
||||||
cli_cmd_flag_none,
|
cli_cmd_flag_none,
|
||||||
"<addr> [duration=<seconds>] = Add a mesh peer" },
|
"<addr> [duration=<seconds>] = Add a mesh peer" },
|
||||||
|
{ "mesh_link_probe", wpa_cli_cmd_mesh_link_probe, NULL,
|
||||||
|
cli_cmd_flag_none,
|
||||||
|
"<addr> [payload=<hex dump of payload>] = Probe a mesh link for a given peer by injecting a frame." },
|
||||||
#endif /* CONFIG_MESH */
|
#endif /* CONFIG_MESH */
|
||||||
#ifdef CONFIG_P2P
|
#ifdef CONFIG_P2P
|
||||||
{ "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
|
{ "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
|
||||||
|
|
Loading…
Reference in a new issue