From patchwork Fri Mar 13 20:27:18 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luca Coelho X-Patchwork-Id: 6009051 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 830FFBF90F for ; Fri, 13 Mar 2015 20:27:38 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 25D0220256 for ; Fri, 13 Mar 2015 20:27:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CB43520274 for ; Fri, 13 Mar 2015 20:27:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753672AbbCMU1e (ORCPT ); Fri, 13 Mar 2015 16:27:34 -0400 Received: from dedo.coelho.fi ([88.198.205.34]:41874 "EHLO dedo.coelho.fi" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1752205AbbCMU1c (ORCPT ); Fri, 13 Mar 2015 16:27:32 -0400 Received: from a88-113-225-236.elisa-laajakaista.fi ([88.113.225.236] helo=dubbel.amr.corp.intel.com) by dedo.coelho.fi with esmtpsa (TLS1.2:RSA_AES_128_CBC_SHA256:128) (Exim 4.80) (envelope-from ) id 1YWWB8-0006LU-P1; Fri, 13 Mar 2015 22:27:31 +0200 From: Luca Coelho To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org Date: Fri, 13 Mar 2015 22:27:18 +0200 Message-Id: <1426278441-10304-2-git-send-email-luca@coelho.fi> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1426278441-10304-1-git-send-email-luca@coelho.fi> References: <1426278441-10304-1-git-send-email-luca@coelho.fi> X-SA-Exim-Connect-IP: 88.113.225.236 X-SA-Exim-Mail-From: luca@coelho.fi X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Subject: [PATCH iw 1/4] iw: move generic sched scan parsing code out of net detect X-SA-Exim-Version: 4.2.1 (built Mon, 26 Dec 2011 16:24:06 +0000) X-SA-Exim-Scanned: Yes (on dedo.coelho.fi) Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Luciano Coelho The scheduled scan structure is pretty much the same as the net-detect WoWLAN trigger's. Move the bulk of the command line parsing code to a generic function so we can reuse it for sched_scan. Signed-off-by: Luciano Coelho --- iw.h | 4 ++ scan.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ wowlan.c | 174 +++------------------------------------------------------------ 3 files changed, 181 insertions(+), 167 deletions(-) diff --git a/iw.h b/iw.h index db88a86..21e2229 100644 --- a/iw.h +++ b/iw.h @@ -173,6 +173,10 @@ void print_ies(unsigned char *ie, int ielen, bool unknown, void parse_bitrate(struct nlattr *bitrate_attr, char *buf, int buflen); void iw_hexdump(const char *prefix, const __u8 *data, size_t len); +#define SCHED_SCAN_OPTIONS "interval [delay " \ + "[freqs +] [matches [ssid ]+]]" +int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv); + DECLARE_SECTION(set); DECLARE_SECTION(get); diff --git a/scan.c b/scan.c index 538b30e..d1c3bf2 100644 --- a/scan.c +++ b/scan.c @@ -99,6 +99,176 @@ static int parse_random_mac_addr(struct nl_msg *msg, char *arg) return -ENOBUFS; } +int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv) +{ + struct nl_msg *matchset = NULL, *freqs = NULL; + struct nlattr *match = NULL; + enum { + ND_TOPLEVEL, + ND_MATCH, + ND_FREQS, + } parse_state = ND_TOPLEVEL; + int c = *argc; + char *end, **v = *argv; + int err = 0, i = 0; + unsigned int freq, interval = 0, delay = 0; + bool have_matchset = false, have_freqs = false; + + matchset = nlmsg_alloc(); + if (!matchset) { + err = -ENOBUFS; + goto out; + } + + freqs = nlmsg_alloc(); + if (!freqs) { + err = -ENOBUFS; + goto out; + } + + while (c) { + switch (parse_state) { + case ND_TOPLEVEL: + if (!strcmp(v[0], "interval")) { + c--; v++; + if (c == 0) { + err = -EINVAL; + goto nla_put_failure; + } + + if (interval) { + err = -EINVAL; + goto nla_put_failure; + } + interval = strtoul(v[0], &end, 10); + if (*end || !interval) { + err = -EINVAL; + goto nla_put_failure; + } + NLA_PUT_U32(msg, + NL80211_ATTR_SCHED_SCAN_INTERVAL, + interval); + } else if (!strcmp(v[0], "delay")) { + c--; v++; + if (c == 0) { + err = -EINVAL; + goto nla_put_failure; + } + + if (delay) { + err = -EINVAL; + goto nla_put_failure; + } + delay = strtoul(v[0], &end, 10); + if (*end) { + err = -EINVAL; + goto nla_put_failure; + } + NLA_PUT_U32(msg, + NL80211_ATTR_SCHED_SCAN_DELAY, + delay); + } else if (!strcmp(v[0], "matches")) { + parse_state = ND_MATCH; + if (have_matchset) { + err = -EINVAL; + goto nla_put_failure; + } + + i = 0; + } else if (!strcmp(v[0], "freqs")) { + parse_state = ND_FREQS; + if (have_freqs) { + err = -EINVAL; + goto nla_put_failure; + } + + have_freqs = true; + i = 0; + } else { + /* this element is not for us, so + * return to continue parsing. + */ + goto nla_put_failure; + } + c--; v++; + + break; + case ND_MATCH: + if (!strcmp(v[0], "ssid")) { + c--; v++; + if (c == 0) { + err = -EINVAL; + goto nla_put_failure; + } + + /* TODO: for now we can only have an + * SSID in the match, so we can start + * the match nest here. + */ + match = nla_nest_start(matchset, i); + if (!match) { + err = -ENOBUFS; + goto nla_put_failure; + } + + NLA_PUT(matchset, + NL80211_SCHED_SCAN_MATCH_ATTR_SSID, + strlen(v[0]), v[0]); + nla_nest_end(matchset, match); + match = NULL; + + have_matchset = true; + i++; + c--; v++; + } else { + /* other element that cannot be part + * of a match indicates the end of the + * match. */ + /* need at least one match in the matchset */ + if (i == 0) { + err = -EINVAL; + goto nla_put_failure; + } + + parse_state = ND_TOPLEVEL; + } + + break; + case ND_FREQS: + freq = strtoul(v[0], &end, 10); + if (*end) { + if (i == 0) { + err = -EINVAL; + goto nla_put_failure; + } + + parse_state = ND_TOPLEVEL; + } else { + NLA_PUT_U32(freqs, i, freq); + i++; + c--; v++; + } + break; + } + } + + if (have_freqs) + nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs); + if (have_matchset) + nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH, matchset); + +nla_put_failure: + if (match) + nla_nest_end(msg, match); + nlmsg_free(freqs); + nlmsg_free(matchset); + +out: + *argc = c; + *argv = v; + return err; +} + static int handle_scan(struct nl80211_state *state, struct nl_cb *cb, struct nl_msg *msg, diff --git a/wowlan.c b/wowlan.c index 12abc76..3a87665 100644 --- a/wowlan.c +++ b/wowlan.c @@ -183,177 +183,17 @@ static int wowlan_parse_tcp_file(struct nl_msg *msg, const char *fn) static int wowlan_parse_net_detect(struct nl_msg *msg, int *argc, char ***argv) { - struct nl_msg *matchset = NULL, *freqs = NULL; - struct nlattr *nd, *match = NULL; - enum { - ND_TOPLEVEL, - ND_MATCH, - ND_FREQS, - } parse_state = ND_TOPLEVEL; - int c = *argc; - char *end, **v = *argv; - int err = 0, i = 0; - unsigned int freq, interval = 0, delay = 0; - bool have_matchset = false, have_freqs = false; + struct nlattr *nd; + int err = 0; nd = nla_nest_start(msg, NL80211_WOWLAN_TRIG_NET_DETECT); - if (!nd) { - err = -ENOBUFS; - goto out; - } - - matchset = nlmsg_alloc(); - if (!matchset) { - err = -ENOBUFS; - goto out; - } - - freqs = nlmsg_alloc(); - if (!freqs) { - err = -ENOBUFS; - goto out; - } - - while (c) { - switch (parse_state) { - case ND_TOPLEVEL: - if (!strcmp(v[0], "interval")) { - c--; v++; - if (c == 0) { - err = -EINVAL; - goto nla_put_failure; - } - - if (interval) { - err = -EINVAL; - goto nla_put_failure; - } - interval = strtoul(v[0], &end, 10); - if (*end || !interval) { - err = -EINVAL; - goto nla_put_failure; - } - NLA_PUT_U32(msg, - NL80211_ATTR_SCHED_SCAN_INTERVAL, - interval); - } else if (!strcmp(v[0], "delay")) { - c--; v++; - if (c == 0) { - err = -EINVAL; - goto nla_put_failure; - } - - if (delay) { - err = -EINVAL; - goto nla_put_failure; - } - delay = strtoul(v[0], &end, 10); - if (*end) { - err = -EINVAL; - goto nla_put_failure; - } - NLA_PUT_U32(msg, - NL80211_ATTR_SCHED_SCAN_DELAY, - delay); - } else if (!strcmp(v[0], "matches")) { - parse_state = ND_MATCH; - if (have_matchset) { - err = -EINVAL; - goto nla_put_failure; - } - - i = 0; - } else if (!strcmp(v[0], "freqs")) { - parse_state = ND_FREQS; - if (have_freqs) { - err = -EINVAL; - goto nla_put_failure; - } - - have_freqs = true; - i = 0; - } else { - /* this element is not for us, so - * return to continue parsing. - */ - goto nla_put_failure; - } - c--; v++; - - break; - case ND_MATCH: - if (!strcmp(v[0], "ssid")) { - c--; v++; - if (c == 0) { - err = -EINVAL; - goto nla_put_failure; - } - - /* TODO: for now we can only have an - * SSID in the match, so we can start - * the match nest here. - */ - match = nla_nest_start(matchset, i); - if (!match) { - err = -ENOBUFS; - goto nla_put_failure; - } - - NLA_PUT(matchset, - NL80211_SCHED_SCAN_MATCH_ATTR_SSID, - strlen(v[0]), v[0]); - nla_nest_end(matchset, match); - match = NULL; - - have_matchset = true; - i++; - c--; v++; - } else { - /* other element that cannot be part - * of a match indicates the end of the - * match. */ - /* need at least one match in the matchset */ - if (i == 0) { - err = -EINVAL; - goto nla_put_failure; - } - - parse_state = ND_TOPLEVEL; - } - - break; - case ND_FREQS: - freq = strtoul(v[0], &end, 10); - if (*end) { - if (i == 0) { - err = -EINVAL; - goto nla_put_failure; - } - - parse_state = ND_TOPLEVEL; - } else { - NLA_PUT_U32(freqs, i, freq); - i++; - c--; v++; - } - break; - } - } + if (!nd) + return -ENOBUFS; - if (have_freqs) - nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs); - if (have_matchset) - nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH, matchset); + err = parse_sched_scan(msg, argc, argv); -nla_put_failure: - if (match) - nla_nest_end(msg, match); - nlmsg_free(freqs); - nlmsg_free(matchset); nla_nest_end(msg, nd); -out: - *argc = c; - *argv = v; + return err; } @@ -473,7 +313,7 @@ static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb, return err; } COMMAND(wowlan, enable, "[any] [disconnect] [magic-packet] [gtk-rekey-failure] [eap-identity-request]" - " [4way-handshake] [rfkill-release] [net-detect interval [delay [freqs +] [matches [ssid ]+]]" + " [4way-handshake] [rfkill-release] [net-detect " SCHED_SCAN_OPTIONS "]" " [tcp ] [patterns [offset1+] ...]", NL80211_CMD_SET_WOWLAN, 0, CIB_PHY, handle_wowlan_enable, "Enable WoWLAN with the given triggers.\n"