Browse Source

nl80211: Extend the new vendor command for testing nl80211

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>
Jouni Malinen 11 years ago
parent
commit
6b9f7af651
1 changed files with 36 additions and 0 deletions
  1. 36 0
      src/drivers/driver_nl80211.c

+ 36 - 0
src/drivers/driver_nl80211.c

@@ -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;