]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wpa_supplicant: Add support to probe mesh link to given peer
authorPradeep Kumar Chitrapu <pradeepc@codeaurora.org>
Mon, 29 Apr 2019 18:42:58 +0000 (11:42 -0700)
committerJouni Malinen <j@w1.fi>
Tue, 28 May 2019 11:38:30 +0000 (14:38 +0300)
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>
wpa_supplicant/ctrl_iface.c
wpa_supplicant/driver_i.h
wpa_supplicant/wpa_cli.c

index 05b7d5f3688252d2a8d2bc670b17e7d448bd80c3..10f1908f8d3409354cf927e211013fb821da78bb 100644 (file)
@@ -8,10 +8,10 @@
 
 #include "utils/includes.h"
 #ifdef CONFIG_TESTING_OPTIONS
-#include <net/ethernet.h>
 #include <netinet/ip.h>
 #endif /* CONFIG_TESTING_OPTIONS */
 
+#include <net/ethernet.h>
 #include "utils/common.h"
 #include "utils/eloop.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);
 }
 
+
+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 */
 
 
@@ -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) {
                if (wpa_supplicant_ctrl_iface_mesh_peer_add(wpa_s, buf + 14))
                        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 */
 #ifdef CONFIG_P2P
        } else if (os_strncmp(buf, "P2P_FIND ", 9) == 0) {
index f073b8a6d14bc1eecc20e869a03dbc887b34d03e..cf9972a6b7d5198f16bdc1f9a10bf2516b5a6636 100644 (file)
@@ -87,6 +87,16 @@ static inline int wpa_drv_leave_mesh(struct wpa_supplicant *wpa_s)
        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,
                               struct wpa_driver_scan_params *params)
 {
index a1ecf8766a3b63ceae0a95e4f90c6d2ec921cca7..5b2154edd799d254314a664de7de96342455ec6b 100644 (file)
@@ -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);
 }
 
+
+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 */
 
 
@@ -3384,6 +3391,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
          cli_cmd_flag_none,
          "<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 */
 #ifdef CONFIG_P2P
        { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,