X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=wowlan.c;h=778c0dbc070488ac40a6d10d81915bb7cb2f5459;hb=cf26fc9ab584833f01e27cc2dd09988179ec6a03;hp=fb7d956aa4b69c2fe024f20caee9b9694e66c471;hpb=d7d39283dcb84432ff71698989970b0ead2b7a6c;p=thirdparty%2Fiw.git diff --git a/wowlan.c b/wowlan.c index fb7d956..778c0db 100644 --- a/wowlan.c +++ b/wowlan.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -160,8 +159,12 @@ static int wowlan_parse_tcp_file(struct nl_msg *msg, const char *fn) tok->offset = atoi(offs); memcpy(tok->token_stream, stream, stream_len); - NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, - sizeof(*tok) + stream_len, tok); + if (nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, + sizeof(*tok) + stream_len, tok) < 0) { + free(stream); + free(tok); + goto nla_put_failure; + } free(stream); free(tok); } else { @@ -177,168 +180,28 @@ static int wowlan_parse_tcp_file(struct nl_msg *msg, const char *fn) err = -ENOBUFS; close: fclose(f); - nla_nest_end(msg, tcp); + if (tcp) + nla_nest_end(msg, tcp); return err; } 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; - 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], "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; } -static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb, +static int handle_wowlan_enable(struct nl80211_state *state, struct nl_msg *msg, int argc, char **argv, enum id_input id) { @@ -454,7 +317,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 [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" @@ -472,10 +335,10 @@ COMMAND(wowlan, enable, "[any] [disconnect] [magic-packet] [gtk-rekey-failure] [ " [data.seq=len,offset[,start]]\n" " [data.tok=len,offset,]\n\n" "Net-detect configuration example:\n" - " iw phy0 wowlan enable net-detect interval 5000 freqs 2412 2422 matches ssid foo ssid bar"); + " iw phy0 wowlan enable net-detect interval 5000 delay 30 freqs 2412 2422 matches ssid foo ssid bar"); -static int handle_wowlan_disable(struct nl80211_state *state, struct nl_cb *cb, +static int handle_wowlan_disable(struct nl80211_state *state, struct nl_msg *msg, int argc, char **argv, enum id_input id) { @@ -529,22 +392,24 @@ static int print_wowlan_handler(struct nl_msg *msg, void *arg) int rem_match; printf(" * wake up on network detection\n"); - nla_parse(nd, NUM_NL80211_ATTR, - nla_data(trig[NL80211_WOWLAN_TRIG_NET_DETECT]), - nla_len(trig[NL80211_WOWLAN_TRIG_NET_DETECT]), NULL); + nla_parse_nested(nd, NL80211_ATTR_MAX, + trig[NL80211_WOWLAN_TRIG_NET_DETECT], NULL); if (nd[NL80211_ATTR_SCHED_SCAN_INTERVAL]) - printf("\tscan interval: %d msecs\n", + printf("\tscan interval: %u msecs\n", nla_get_u32(nd[NL80211_ATTR_SCHED_SCAN_INTERVAL])); + if (nd[NL80211_ATTR_SCHED_SCAN_DELAY]) + printf("\tinitial scan delay: %u secs\n", + nla_get_u32(nd[NL80211_ATTR_SCHED_SCAN_DELAY])); + if (nd[NL80211_ATTR_SCHED_SCAN_MATCH]) { printf("\tmatches:\n"); nla_for_each_nested(match, nd[NL80211_ATTR_SCHED_SCAN_MATCH], rem_match) { - nla_parse(tb, NUM_NL80211_ATTR, nla_data(match), - nla_len(match), - NULL); + nla_parse_nested(tb, NL80211_ATTR_MAX, match, + NULL); printf("\t\tSSID: "); print_ssid_escaped( nla_len(tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]), @@ -607,12 +472,11 @@ static int print_wowlan_handler(struct nl_msg *msg, void *arg) return NL_SKIP; } -static int handle_wowlan_show(struct nl80211_state *state, struct nl_cb *cb, +static int handle_wowlan_show(struct nl80211_state *state, struct nl_msg *msg, int argc, char **argv, enum id_input id) { - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, - print_wowlan_handler, NULL); + register_handler(print_wowlan_handler, NULL); return 0; }