Search Linux Wireless

[PATCH v3] iw: add packet offset information for wowlan pattern

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Amitkumar Karwar <akarwar@xxxxxxxxxxx>

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@xxxxxxxxxxx>
Signed-off-by: Bing Zhao <bzhao@xxxxxxxxxxx>
---
v3: check struct size to avoid crash on old kernels; and use
    '+' delimiter between offset and pattern. (Johannes Berg)
v2: display maximum permissible packet offset as well for
    WOWLAN patterns

 info.c   | 11 ++++++-----
 wowlan.c | 36 +++++++++++++++++++++++++++++-------
 2 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/info.c b/info.c
index 4cdbda7..a1018a2 100644
--- 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] = { .type = NLA_NESTED },
 			[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");
diff --git a/wowlan.c b/wowlan.c
index 0093a87..4be43d9 100644
--- 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++) {
-- 
1.8.0

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux