]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
iw: add packet offset information for wowlan pattern
authorAmitkumar Karwar <akarwar@marvell.com>
Wed, 20 Feb 2013 00:44:44 +0000 (16:44 -0800)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 20 Feb 2013 10:03:08 +0000 (11:03 +0100)
Now user can provide packet offset along with the pattern in
"iw wowlan" command. Default offset will be 0 when it is not
provided.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
info.c
wowlan.c

diff --git a/info.c b/info.c
index 4cdbda70a5a628be2a7a45e7bc3b1a5adee6871d..390ef6dbd7e6faa54f979633cebe6a7449095f54 100644 (file)
--- a/info.c
+++ b/info.c
@@ -400,9 +400,7 @@ broken_combination:
                        [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG },
                        [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
                        [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
-                       [NL80211_WOWLAN_TRIG_PKT_PATTERN] = {
-                               .minlen = sizeof(struct nl80211_wowlan_pattern_support),
-                       },
+                       [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .minlen = 12 },
                        [NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED] = { .type = NLA_FLAG },
                        [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
                        [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
@@ -429,8 +427,11 @@ broken_combination:
                                printf("\t\t * wake up on magic packet\n");
                        if (tb_wowlan[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
                                pat = nla_data(tb_wowlan[NL80211_WOWLAN_TRIG_PKT_PATTERN]);
-                               printf("\t\t * wake up on pattern match, up to %u patterns of %u-%u bytes\n",
-                                       pat->max_patterns, pat->min_pattern_len, pat->max_pattern_len);
+                               printf("\t\t * wake up on pattern match, up to %u patterns of %u-%u bytes,\n"
+                                       "\t\t   maximum packet offset %u bytes\n",
+                                       pat->max_patterns, pat->min_pattern_len, pat->max_pattern_len,
+                                       (nla_len(tb_wowlan[NL80211_WOWLAN_TRIG_PKT_PATTERN]) <
+                                       sizeof(*pat)) ? 0 : pat->max_pkt_offset);
                        }
                        if (tb_wowlan[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
                                printf("\t\t * can do GTK rekeying\n");
index 0093a870241c86c84babb004f3812762954b8462..4be43d96e6919e0dba9caebe1fce7070a0de6c6d 100644 (file)
--- a/wowlan.c
+++ b/wowlan.c
@@ -194,7 +194,8 @@ static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb,
        int err = -ENOBUFS;
        unsigned char *pat, *mask;
        size_t patlen;
-       int patnum = 0;
+       int patnum = 0, pkt_offset;
+       char *eptr, *value1, *value2, *sptr = NULL;
 
        wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS);
        if (!wowlan)
@@ -240,15 +241,31 @@ static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb,
                        }
                        break;
                case PS_PAT:
-                       if (parse_hex_mask(argv[0], &pat, &patlen, &mask)) {
+                       value1 = strtok_r(argv[0], "+", &sptr);
+                       value2 = strtok_r(NULL, "+", &sptr);
+
+                       if (!value2) {
+                               pkt_offset = 0;
+                               value2 = value1;
+                       } else {
+                               pkt_offset = strtoul(value1, &eptr, 10);
+                               if (eptr != value1 + strlen(value1)) {
+                                       err = 1;
+                                       goto nla_put_failure;
+                               }
+                       }
+
+                       if (parse_hex_mask(value2, &pat, &patlen, &mask)) {
                                err = 1;
                                goto nla_put_failure;
                        }
+
                        pattern = nla_nest_start(patterns, ++patnum);
                        NLA_PUT(patterns, NL80211_WOWLAN_PKTPAT_MASK,
                                DIV_ROUND_UP(patlen, 8), mask);
                        NLA_PUT(patterns, NL80211_WOWLAN_PKTPAT_PATTERN,
                                patlen, pat);
+                       NLA_PUT_U32(patterns, NL80211_WOWLAN_PKTPAT_OFFSET, pkt_offset);
                        nla_nest_end(patterns, pattern);
                        free(mask);
                        free(pat);
@@ -269,12 +286,14 @@ 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] [tcp <config-file>] [patterns <pattern>*]",
+       " [4way-handshake] [rfkill-release] [tcp <config-file>] [patterns [offset1+]<pattern1> ...]",
        NL80211_CMD_SET_WOWLAN, 0, CIB_PHY, handle_wowlan_enable,
        "Enable WoWLAN with the given triggers.\n"
        "Each pattern is given as a bytestring with '-' in places where any byte\n"
        "may be present, e.g. 00:11:22:-:44 will match 00:11:22:33:44 and\n"
-       "00:11:22:33:ff:44 etc.\n\n"
+       "00:11:22:33:ff:44 etc.\n"
+       "Offset and pattern should be separated by '+', e.g. 18+43:34:00:12 will match "
+       "'43:34:00:12' after 18 bytes of offset in Rx packet.\n\n"
        "The TCP configuration file contains:\n"
        "  source=ip[:port]\n"
        "  dest=ip:port@mac\n"
@@ -338,23 +357,26 @@ static int print_wowlan_handler(struct nl_msg *msg, void *arg)
                                    trig[NL80211_WOWLAN_TRIG_PKT_PATTERN],
                                    rem_pattern) {
                        struct nlattr *patattr[NUM_NL80211_WOWLAN_PKTPAT];
-                       int i, patlen, masklen;
+                       int i, patlen, masklen, pkt_offset;
                        uint8_t *mask, *pat;
                        nla_parse(patattr, MAX_NL80211_WOWLAN_PKTPAT,
                                  nla_data(pattern), nla_len(pattern),
                                  NULL);
                        if (!patattr[NL80211_WOWLAN_PKTPAT_MASK] ||
-                           !patattr[NL80211_WOWLAN_PKTPAT_PATTERN]) {
+                           !patattr[NL80211_WOWLAN_PKTPAT_PATTERN] ||
+                           !patattr[NL80211_WOWLAN_PKTPAT_OFFSET]) {
                                printf(" * (invalid pattern specification)\n");
                                continue;
                        }
                        masklen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_MASK]);
                        patlen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]);
+                       pkt_offset = nla_get_u32(patattr[NL80211_WOWLAN_PKTPAT_OFFSET]);
                        if (DIV_ROUND_UP(patlen, 8) != masklen) {
                                printf(" * (invalid pattern specification)\n");
                                continue;
                        }
-                       printf(" * wake up on pattern: ");
+                       printf(" * wake up on packet offset: %d", pkt_offset);
+                       printf(" pattern: ");
                        pat = nla_data(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]);
                        mask = nla_data(patattr[NL80211_WOWLAN_PKTPAT_MASK]);
                        for (i = 0; i < patlen; i++) {