mesh: Write close reason from Mesh Peering Close to debug log
[mech_eap.git] / wpa_supplicant / wpa_cli.c
index 48897d4..53036ae 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * WPA Supplicant - command line interface for wpa_supplicant daemon
- * Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -28,7 +28,7 @@
 
 static const char *const wpa_cli_version =
 "wpa_cli v" VERSION_STR "\n"
-"Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi> and contributors";
+"Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> and contributors";
 
 
 static const char *const wpa_cli_license =
@@ -66,6 +66,12 @@ static const char *const wpa_cli_full_license =
 "OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
 "\n";
 
+#define VENDOR_ELEM_FRAME_ID \
+       "  0: Probe Req (P2P), 1: Probe Resp (P2P) , 2: Probe Resp (GO), " \
+       "3: Beacon (GO), 4: PD Req, 5: PD Resp, 6: GO Neg Req, " \
+       "7: GO Neg Resp, 8: GO Neg Conf, 9: Inv Req, 10: Inv Resp, " \
+       "11: Assoc Req (P2P), 12: Assoc Resp (P2P)"
+
 static struct wpa_ctrl *ctrl_conn;
 static struct wpa_ctrl *mon_conn;
 static int wpa_cli_quit = 0;
@@ -76,6 +82,7 @@ static int wpa_cli_last_id = 0;
 #define CONFIG_CTRL_IFACE_DIR "/var/run/wpa_supplicant"
 #endif /* CONFIG_CTRL_IFACE_DIR */
 static const char *ctrl_iface_dir = CONFIG_CTRL_IFACE_DIR;
+static const char *client_socket_dir = NULL;
 static char *ctrl_ifname = NULL;
 static const char *pid_file = NULL;
 static const char *action_file = NULL;
@@ -107,7 +114,9 @@ static void usage(void)
 {
        printf("wpa_cli [-p<path to ctrl sockets>] [-i<ifname>] [-hvB] "
               "[-a<action file>] \\\n"
-              "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>]  "
+              "        [-P<pid file>] [-g<global ctrl>] [-G<ping interval>] "
+              "\\\n"
+              "        [-s<wpa_client_socket_file_path>] "
               "[command..]\n"
               "  -h = help (show this usage text)\n"
               "  -v = shown version information\n"
@@ -330,6 +339,13 @@ static int wpa_cli_open_connection(const char *ifname, int attach)
        }
 #endif /* ANDROID */
 
+       if (client_socket_dir && client_socket_dir[0] &&
+           access(client_socket_dir, F_OK) < 0) {
+               perror(client_socket_dir);
+               os_free(cfile);
+               return -1;
+       }
+
        if (cfile == NULL) {
                flen = os_strlen(ctrl_iface_dir) + os_strlen(ifname) + 2;
                cfile = os_malloc(flen);
@@ -343,14 +359,14 @@ static int wpa_cli_open_connection(const char *ifname, int attach)
                }
        }
 
-       ctrl_conn = wpa_ctrl_open(cfile);
+       ctrl_conn = wpa_ctrl_open2(cfile, client_socket_dir);
        if (ctrl_conn == NULL) {
                os_free(cfile);
                return -1;
        }
 
        if (attach && interactive)
-               mon_conn = wpa_ctrl_open(cfile);
+               mon_conn = wpa_ctrl_open2(cfile, client_socket_dir);
        else
                mon_conn = NULL;
        os_free(cfile);
@@ -502,6 +518,10 @@ static int wpa_cli_cmd_status(struct wpa_ctrl *ctrl, int argc, char *argv[])
                return wpa_ctrl_command(ctrl, "STATUS-WPS");
        if (argc > 0 && os_strcmp(argv[0], "driver") == 0)
                return wpa_ctrl_command(ctrl, "STATUS-DRIVER");
+#ifdef ANDROID
+       if (argc > 0 && os_strcmp(argv[0], "no_events") == 0)
+               return wpa_ctrl_command(ctrl, "STATUS-NO_EVENTS");
+#endif /* ANDROID */
        return wpa_ctrl_command(ctrl, "STATUS");
 }
 
@@ -618,6 +638,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos)
                "eapol_version", "ap_scan", "bgscan",
 #ifdef CONFIG_MESH
                "user_mpm", "max_peer_links", "mesh_max_inactivity",
+               "dot11RSNASAERetransPeriod",
 #endif /* CONFIG_MESH */
                "disable_scan_offload", "fast_reauth", "opensc_engine_path",
                "pkcs11_engine_path", "pkcs11_module_path", "openssl_ciphers",
@@ -1533,7 +1554,7 @@ static const char *network_fields[] = {
        "ssid", "scan_ssid", "bssid", "bssid_blacklist",
        "bssid_whitelist", "psk", "proto", "key_mgmt",
        "bg_scan_period", "pairwise", "group", "auth_alg", "scan_freq",
-       "freq_list",
+       "freq_list", "max_oper_chwidth",
 #ifdef IEEE8021X_EAPOL
        "eap", "identity", "anonymous_identity", "password", "ca_cert",
        "ca_path", "client_cert", "private_key", "private_key_passwd",
@@ -1591,7 +1612,7 @@ static const char *network_fields[] = {
 #ifdef CONFIG_HS20
        "update_identifier",
 #endif /* CONFIG_HS20 */
-       "mac_addr"
+       "mac_addr", "pbss", "wps_disabled"
 };
 
 
@@ -1749,6 +1770,13 @@ static int wpa_cli_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
 }
 
 
+static int wpa_cli_cmd_abort_scan(struct wpa_ctrl *ctrl, int argc,
+                                 char *argv[])
+{
+       return wpa_ctrl_command(ctrl, "ABORT_SCAN");
+}
+
+
 static int wpa_cli_cmd_bss(struct wpa_ctrl *ctrl, int argc, char *argv[])
 {
        return wpa_cli_cmd(ctrl, "BSS", 1, argc, argv);
@@ -1851,14 +1879,15 @@ static int wpa_cli_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
 
        /*
         * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
-        * <driver_param>TAB<bridge_name>[TAB<create>]
+        * <driver_param>TAB<bridge_name>[TAB<create>[TAB<type>]]
         */
        res = os_snprintf(cmd, sizeof(cmd),
-                         "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s",
+                         "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s",
                          argv[0],
                          argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
                          argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
-                         argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "");
+                         argc > 5 ? argv[5] : "", argc > 6 ? argv[6] : "",
+                         argc > 7 ? argv[7] : "");
        if (os_snprintf_error(sizeof(cmd), res))
                return -1;
        cmd[sizeof(cmd) - 1] = '\0';
@@ -1898,6 +1927,12 @@ static int wpa_ctrl_command_sta(struct wpa_ctrl *ctrl, char *cmd,
                printf("Not connected to hostapd - command dropped.\n");
                return -1;
        }
+       if (ifname_prefix) {
+               os_snprintf(buf, sizeof(buf), "IFNAME=%s %s",
+                           ifname_prefix, cmd);
+               buf[sizeof(buf) - 1] = '\0';
+               cmd = buf;
+       }
        len = sizeof(buf) - 1;
        ret = wpa_ctrl_request(ctrl, cmd, os_strlen(cmd), buf, &len,
                               wpa_cli_msg_cb);
@@ -2007,6 +2042,20 @@ static int wpa_cli_cmd_mesh_group_remove(struct wpa_ctrl *ctrl, int argc,
        return wpa_cli_cmd(ctrl, "MESH_GROUP_REMOVE", 1, argc, argv);
 }
 
+
+static int wpa_cli_cmd_mesh_peer_remove(struct wpa_ctrl *ctrl, int argc,
+                                       char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "MESH_PEER_REMOVE", 1, argc, argv);
+}
+
+
+static int wpa_cli_cmd_mesh_peer_add(struct wpa_ctrl *ctrl, int argc,
+                                    char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "MESH_PEER_ADD", 1, argc, argv);
+}
+
 #endif /* CONFIG_MESH */
 
 
@@ -2126,6 +2175,13 @@ static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
 }
 
 
+static int wpa_cli_cmd_p2p_group_member(struct wpa_ctrl *ctrl, int argc,
+                                       char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "P2P_GROUP_MEMBER", 1, argc, argv);
+}
+
+
 static int wpa_cli_cmd_p2p_prov_disc(struct wpa_ctrl *ctrl, int argc,
                                     char *argv[])
 {
@@ -2462,6 +2518,27 @@ static int wpa_cli_cmd_p2p_remove_client(struct wpa_ctrl *ctrl, int argc,
        return wpa_cli_cmd(ctrl, "P2P_REMOVE_CLIENT", 1, argc, argv);
 }
 
+
+static int wpa_cli_cmd_vendor_elem_add(struct wpa_ctrl *ctrl, int argc,
+                                      char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "VENDOR_ELEM_ADD", 2, argc, argv);
+}
+
+
+static int wpa_cli_cmd_vendor_elem_get(struct wpa_ctrl *ctrl, int argc,
+                                      char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "VENDOR_ELEM_GET", 1, argc, argv);
+}
+
+
+static int wpa_cli_cmd_vendor_elem_remove(struct wpa_ctrl *ctrl, int argc,
+                                         char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "VENDOR_ELEM_REMOVE", 2, argc, argv);
+}
+
 #endif /* CONFIG_P2P */
 
 #ifdef CONFIG_WIFI_DISPLAY
@@ -2704,6 +2781,13 @@ static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc,
 }
 
 
+static int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc,
+                                  char *argv[])
+{
+       return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv);
+}
+
+
 static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc,
                                   char *argv[])
 {
@@ -2986,6 +3070,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "scan_results", wpa_cli_cmd_scan_results, NULL,
          cli_cmd_flag_none,
          "= get latest scan results" },
+       { "abort_scan", wpa_cli_cmd_abort_scan, NULL,
+         cli_cmd_flag_none,
+         "= request ongoing scan to be aborted" },
        { "bss", wpa_cli_cmd_bss, wpa_cli_complete_bss,
          cli_cmd_flag_none,
          "<<idx> | <bssid>> = get detailed scan result info" },
@@ -3002,8 +3089,10 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "interface_add", wpa_cli_cmd_interface_add, NULL,
          cli_cmd_flag_none,
          "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
-         "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
-         "  are optional" },
+         "  <bridge_name> <create> <type> = adds new interface, all "
+         "parameters but\n"
+         "  <ifname> are optional. Supported types are station ('sta') and "
+         "AP ('ap')" },
        { "interface_remove", wpa_cli_cmd_interface_remove, NULL,
          cli_cmd_flag_none,
          "<ifname> = removes the interface" },
@@ -3142,6 +3231,12 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "mesh_group_remove", wpa_cli_cmd_mesh_group_remove, NULL,
          cli_cmd_flag_none,
          "<ifname> = Remove mesh group interface" },
+       { "mesh_peer_remove", wpa_cli_cmd_mesh_peer_remove, NULL,
+         cli_cmd_flag_none,
+         "<addr> = Remove a mesh peer" },
+       { "mesh_peer_add", wpa_cli_cmd_mesh_peer_add, NULL,
+         cli_cmd_flag_none,
+         "<addr> [duration=<seconds>] = Add a mesh peer" },
 #endif /* CONFIG_MESH */
 #ifdef CONFIG_P2P
        { "p2p_find", wpa_cli_cmd_p2p_find, wpa_cli_complete_p2p_find,
@@ -3165,6 +3260,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
          "<ifname> = remove P2P group interface (terminate group if GO)" },
        { "p2p_group_add", wpa_cli_cmd_p2p_group_add, NULL, cli_cmd_flag_none,
          "[ht40] = add a new P2P group (local end as GO)" },
+       { "p2p_group_member", wpa_cli_cmd_p2p_group_member, NULL,
+         cli_cmd_flag_none,
+         "<dev_addr> = Get peer interface address on local GO using peer Device Address" },
        { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc,
          wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
          "<addr> <method> = request provisioning discovery" },
@@ -3233,6 +3331,18 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "p2p_remove_client", wpa_cli_cmd_p2p_remove_client,
          wpa_cli_complete_p2p_peer, cli_cmd_flag_none,
          "<address|iface=address> = remove a peer from all groups" },
+       { "vendor_elem_add", wpa_cli_cmd_vendor_elem_add, NULL,
+         cli_cmd_flag_none,
+         "<frame id> <hexdump of elem(s)> = add vendor specific IEs to frame(s)\n"
+         VENDOR_ELEM_FRAME_ID },
+       { "vendor_elem_get", wpa_cli_cmd_vendor_elem_get, NULL,
+         cli_cmd_flag_none,
+         "<frame id> = get vendor specific IE(s) to frame(s)\n"
+         VENDOR_ELEM_FRAME_ID },
+       { "vendor_elem_remove", wpa_cli_cmd_vendor_elem_remove, NULL,
+         cli_cmd_flag_none,
+         "<frame id> <hexdump of elem(s)> = remove vendor specific IE(s) in frame(s)\n"
+         VENDOR_ELEM_FRAME_ID },
 #endif /* CONFIG_P2P */
 #ifdef CONFIG_WIFI_DISPLAY
        { "wfd_subelem_set", wpa_cli_cmd_wfd_subelem_set, NULL,
@@ -3321,6 +3431,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "signal_poll", wpa_cli_cmd_signal_poll, NULL,
          cli_cmd_flag_none,
          "= get signal parameters" },
+       { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL,
+         cli_cmd_flag_none,
+         "= set signal monitor parameters" },
        { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL,
          cli_cmd_flag_none,
          "= get TX/RX packet counters" },
@@ -3335,7 +3448,7 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        { "wnm_sleep", wpa_cli_cmd_wnm_sleep, NULL, cli_cmd_flag_none,
          "<enter/exit> [interval=#] = enter/exit WNM-Sleep mode" },
        { "wnm_bss_query", wpa_cli_cmd_wnm_bss_query, NULL, cli_cmd_flag_none,
-         "<query reason> = Send BSS Transition Management Query" },
+         "<query reason> [list] = Send BSS Transition Management Query" },
 #endif /* CONFIG_WNM */
        { "raw", wpa_cli_cmd_raw, NULL, cli_cmd_flag_sensitive,
          "<params..> = Sent unprocessed command" },
@@ -3352,8 +3465,7 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = {
        },
        { "neighbor_rep_request",
          wpa_cli_cmd_neighbor_rep_request, NULL, cli_cmd_flag_none,
-         "[ssid=<SSID>] = Trigger request to AP for neighboring AP report "
-         "(with optional given SSID, default: current SSID)"
+         "[ssid=<SSID>] [lci] [civic] = Trigger request to AP for neighboring AP report (with optional given SSID in hex or enclosed in double quotes, default: current SSID; with optional LCI and location civic request)"
        },
        { "erp_flush", wpa_cli_cmd_erp_flush, NULL, cli_cmd_flag_none,
          "= flush ERP keys" },
@@ -3576,6 +3688,10 @@ static int wpa_cli_exec(const char *program, const char *arg1,
        size_t len;
        int res;
 
+       /* If no interface is specified, set the global */
+       if (!arg1)
+               arg1 = "global";
+
        len = os_strlen(arg1) + os_strlen(arg2) + 2;
        arg = os_malloc(len);
        if (arg == NULL)
@@ -3661,6 +3777,10 @@ static void wpa_cli_action_process(const char *msg)
                        wpa_cli_connected = 0;
                        wpa_cli_exec(action_file, ifname, "DISCONNECTED");
                }
+       } else if (str_match(pos, AP_EVENT_ENABLED)) {
+               wpa_cli_exec(action_file, ctrl_ifname, pos);
+       } else if (str_match(pos, AP_EVENT_DISABLED)) {
+               wpa_cli_exec(action_file, ctrl_ifname, pos);
        } else if (str_match(pos, MESH_GROUP_STARTED)) {
                wpa_cli_exec(action_file, ctrl_ifname, pos);
        } else if (str_match(pos, MESH_GROUP_REMOVED)) {
@@ -4069,7 +4189,7 @@ static void try_connection(void *eloop_ctx, void *timeout_ctx)
        if (ctrl_ifname == NULL)
                ctrl_ifname = wpa_cli_get_default_ifname();
 
-       if (!wpa_cli_open_connection(ctrl_ifname, 1) == 0) {
+       if (wpa_cli_open_connection(ctrl_ifname, 1)) {
                if (!warning_displayed) {
                        printf("Could not connect to wpa_supplicant: "
                               "%s - re-trying\n",
@@ -4179,18 +4299,17 @@ static char * wpa_cli_get_default_ifname(void)
 {
        char *ifname = NULL;
 
+#ifdef ANDROID
+       char ifprop[PROPERTY_VALUE_MAX];
+       if (property_get("wifi.interface", ifprop, NULL) != 0) {
+               ifname = os_strdup(ifprop);
+               printf("Using interface '%s'\n", ifname ? ifname : "N/A");
+       }
+#else /* ANDROID */
 #ifdef CONFIG_CTRL_IFACE_UNIX
        struct dirent *dent;
        DIR *dir = opendir(ctrl_iface_dir);
        if (!dir) {
-#ifdef ANDROID
-               char ifprop[PROPERTY_VALUE_MAX];
-               if (property_get("wifi.interface", ifprop, NULL) != 0) {
-                       ifname = os_strdup(ifprop);
-                       printf("Using interface '%s'\n", ifname);
-                       return ifname;
-               }
-#endif /* ANDROID */
                return NULL;
        }
        while ((dent = readdir(dir))) {
@@ -4234,6 +4353,7 @@ static char * wpa_cli_get_default_ifname(void)
        }
        wpa_ctrl_close(ctrl);
 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
+#endif /* ANDROID */
 
        return ifname;
 }
@@ -4250,7 +4370,7 @@ int main(int argc, char *argv[])
                return -1;
 
        for (;;) {
-               c = getopt(argc, argv, "a:Bg:G:hi:p:P:v");
+               c = getopt(argc, argv, "a:Bg:G:hi:p:P:s:v");
                if (c < 0)
                        break;
                switch (c) {
@@ -4282,6 +4402,9 @@ int main(int argc, char *argv[])
                case 'P':
                        pid_file = optarg;
                        break;
+               case 's':
+                       client_socket_dir = optarg;
+                       break;
                default:
                        usage();
                        return -1;
@@ -4355,7 +4478,7 @@ int main(int argc, char *argv[])
                        }
                }
 
-               if (daemonize && os_daemonize(pid_file))
+               if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue())
                        return -1;
 
                if (action_file)