#include <net/if.h>
#include <errno.h>
#include <string.h>
-#include <ctype.h>
#include <stdbool.h>
#include <netlink/genl/genl.h>
int parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv)
{
struct nl_msg *matchset = NULL, *freqs = NULL, *ssids = NULL;
- struct nlattr *match = NULL;
+ struct nl_msg *scan_plans = NULL;
+ struct nlattr *match = NULL, *plan = NULL;
enum {
ND_TOPLEVEL,
ND_MATCH,
ND_FREQS,
ND_ACTIVE,
+ ND_PLANS,
} parse_state = ND_TOPLEVEL;
int c = *argc;
char *end, **v = *argv;
int err = 0, i = 0;
- unsigned int freq, interval = 0, delay = 0;
+ unsigned int freq, interval = 0, delay = 0, iterations = 0;
bool have_matchset = false, have_freqs = false, have_ssids = false;
- bool have_active = false, have_passive = false;
+ bool have_active = false, have_passive = false, have_plans = false;
uint32_t flags = 0;
matchset = nlmsg_alloc();
goto out;
}
+ scan_plans = nlmsg_alloc();
+ if (!scan_plans) {
+ err = -ENOBUFS;
+ goto out;
+ }
+
while (c) {
switch (parse_state) {
case ND_TOPLEVEL:
goto nla_put_failure;
}
- if (interval) {
+ if (interval || have_plans) {
err = -EINVAL;
goto nla_put_failure;
}
NLA_PUT_U32(msg,
NL80211_ATTR_SCHED_SCAN_INTERVAL,
interval);
+ } else if (!strcmp(v[0], "scan_plans")) {
+ parse_state = ND_PLANS;
+ if (have_plans || interval) {
+ err = -EINVAL;
+ goto nla_put_failure;
+ }
+
+ have_plans = true;
+ i = 0;
} else if (!strcmp(v[0], "delay")) {
c--; v++;
if (c == 0) {
parse_state = ND_TOPLEVEL;
}
break;
+ case ND_PLANS:
+ iterations = 0;
+ interval = strtoul(v[0], &end, 10);
+ if (*end) {
+ char *iter;
+
+ if (*end != ':') {
+ err = -EINVAL;
+ goto nla_put_failure;
+ }
+
+ iter = ++end;
+ iterations = strtoul(iter, &end, 10);
+ if (*end || !iterations) {
+ err = -EINVAL;
+ goto nla_put_failure;
+ }
+ }
+
+ plan = nla_nest_start(scan_plans, i + 1);
+ if (!plan) {
+ err = -ENOBUFS;
+ goto nla_put_failure;
+ }
+
+ NLA_PUT_U32(scan_plans,
+ NL80211_SCHED_SCAN_PLAN_INTERVAL,
+ interval);
+
+ if (iterations)
+ NLA_PUT_U32(scan_plans,
+ NL80211_SCHED_SCAN_PLAN_ITERATIONS,
+ iterations);
+ else
+ parse_state = ND_TOPLEVEL;
+
+ nla_nest_end(scan_plans, plan);
+ plan = NULL;
+ i++;
+ c--; v++;
+ break;
}
}
nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
if (have_matchset)
nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH, matchset);
+ if (have_plans)
+ nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_PLANS, scan_plans);
if (flags)
NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, flags);
nla_nest_end(msg, match);
nlmsg_free(freqs);
nlmsg_free(matchset);
+ nlmsg_free(scan_plans);
out:
*argc = c;
memcpy(&tmpies[ies_len], meshid, meshid_len);
free(meshid);
}
- NLA_PUT(msg, NL80211_ATTR_IE, ies_len + meshid_len, tmpies);
+ if (nla_put(msg, NL80211_ATTR_IE, ies_len + meshid_len, tmpies) < 0) {
+ free(tmpies);
+ goto nla_put_failure;
+ }
free(tmpies);
}
}
printf("\n");
+ if (bss[NL80211_BSS_LAST_SEEN_BOOTTIME]) {
+ unsigned long long bt;
+ bt = (unsigned long long)nla_get_u64(bss[NL80211_BSS_LAST_SEEN_BOOTTIME]);
+ printf("\tlast seen: %llu.%.3llus [boottime]\n", bt/1000000000, (bt%1000000000)/1000000);
+ }
+
if (bss[NL80211_BSS_TSF]) {
unsigned long long tsf;
tsf = (unsigned long long)nla_get_u64(bss[NL80211_BSS_TSF]);