From 6b9f7af651f80ddbdb949ce1d1352aab9aa53022 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 5 Mar 2014 17:19:58 +0200 Subject: [PATCH] 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 --- src/drivers/driver_nl80211.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 7468e5d19..6a2af9511 100644 --- a/src/drivers/driver_nl80211.c +++ b/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;