]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Extend the new vendor command for testing nl80211
authorJouni Malinen <jouni@qca.qualcomm.com>
Wed, 5 Mar 2014 15:19:58 +0000 (17:19 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 5 Mar 2014 15:19:58 +0000 (17:19 +0200)
CONFIG_TESTING_OPTIONS=y build of wpa_supplicant now allows arbitrary
cfg80211 commands to be performed through the new VENDOR ctrl_iface
command by using a special vendor_id ffffffff. The command identifier
(NL80211_CMD_*) is encoded as the subcmd and the attributes in the
hexformatted data area. Response attributes are returned as a hexdump.

For example, this shows a NL80211_CMD_FRAME and a response (cookie
attribute) on a little endian host:

wpa_cli -i wlan0 vendor ffffffff 59 080003004d0000000800260085090000....
0c00580000d7868c0388ffff

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/drivers/driver_nl80211.c

index 7468e5d193d680423250bb81c78ca301dcc4ea96..6a2af9511bdca2d117829903553dc3bd679c41ca 100644 (file)
@@ -11720,6 +11720,28 @@ error:
 }
 
 
+#ifdef CONFIG_TESTING_OPTIONS
+static int cmd_reply_handler(struct nl_msg *msg, void *arg)
+{
+       struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+       struct wpabuf *buf = arg;
+
+       if (!buf)
+               return NL_SKIP;
+
+       if ((size_t) genlmsg_attrlen(gnlh, 0) > wpabuf_tailroom(buf)) {
+               wpa_printf(MSG_INFO, "nl80211: insufficient buffer space for reply");
+               return NL_SKIP;
+       }
+
+       wpabuf_put_data(buf, genlmsg_attrdata(gnlh, 0),
+                       genlmsg_attrlen(gnlh, 0));
+
+       return NL_SKIP;
+}
+#endif /* CONFIG_TESTING_OPTIONS */
+
+
 static int vendor_reply_handler(struct nl_msg *msg, void *arg)
 {
        struct nlattr *tb[NL80211_ATTR_MAX + 1];
@@ -11764,6 +11786,20 @@ static int nl80211_vendor_cmd(void *priv, unsigned int vendor_id,
        if (!msg)
                return -ENOMEM;
 
+#ifdef CONFIG_TESTING_OPTIONS
+       if (vendor_id == 0xffffffff) {
+               nl80211_cmd(drv, msg, 0, subcmd);
+               if (nlmsg_append(msg, (void *) data, data_len, NLMSG_ALIGNTO) <
+                   0)
+                       goto nla_put_failure;
+               ret = send_and_recv_msgs(drv, msg, cmd_reply_handler, buf);
+               if (ret)
+                       wpa_printf(MSG_DEBUG, "nl80211: command failed err=%d",
+                                  ret);
+               return ret;
+       }
+#endif /* CONFIG_TESTING_OPTIONS */
+
        nl80211_cmd(drv, msg, 0, NL80211_CMD_VENDOR);
        if (nl80211_set_iface_id(msg, bss) < 0)
                goto nla_put_failure;