@@ -202,6 +202,7 @@ struct iwinfo_ops {
int (*assoclist)(const char *, char *, int *);
int (*txpwrlist)(const char *, char *, int *);
int (*scanlist)(const char *, char *, int *);
+ int (*scanlist2)(const char *, char *, int *, unsigned int);
int (*freqlist)(const char *, char *, int *);
int (*countrylist)(const char *, char *, int *);
int (*lookup_phy)(const char *, char *);
@@ -562,18 +562,32 @@ static void print_info(const struct iwinfo_ops *iw, const char *ifname)
}
-static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname)
+static void print_scanlist(const struct iwinfo_ops *iw, const char *ifname, unsigned int freq)
{
int i, x, len;
char buf[IWINFO_BUFSIZE];
struct iwinfo_scanlist_entry *e;
- if (iw->scanlist(ifname, buf, &len))
+ if (freq)
+ {
+ if (!iw->scanlist2)
+ {
+ printf("Scanning of specific frequency not implemented\n\n");
+ return;
+ }
+ if (iw->scanlist2(ifname, buf, &len, freq))
+ {
+ printf("Scanning of specific frequency not possible\n\n");
+ return;
+ }
+ }
+ else if (iw->scanlist(ifname, buf, &len))
{
printf("Scanning not possible\n\n");
return;
}
- else if (len <= 0)
+
+ if (len <= 0)
{
printf("No scan results\n\n");
return;
@@ -794,6 +808,7 @@ int main(int argc, char **argv)
"Usage:\n"
" iwinfo <device> info\n"
" iwinfo <device> scan\n"
+ " iwinfo <device> scan <freq>\n"
" iwinfo <device> txpowerlist\n"
" iwinfo <device> freqlist\n"
" iwinfo <device> assoclist\n"
@@ -831,25 +846,37 @@ int main(int argc, char **argv)
if (argc > 3)
{
- iw = iwinfo_backend_by_name(argv[1]);
-
- if (!iw)
- {
- fprintf(stderr, "No such wireless backend: %s\n", argv[1]);
- rv = 1;
- }
- else
+ switch (argv[2][0])
{
- switch (argv[2][0])
+ case 'p':
+ iw = iwinfo_backend_by_name(argv[1]);
+
+ if (!iw)
{
- case 'p':
- lookup_phy(iw, argv[3]);
- break;
+ fprintf(stderr, "No such wireless backend: %s\n", argv[1]);
+ rv = 1;
+ goto finish;
+ }
+
+ lookup_phy(iw, argv[3]);
+ break;
+
+ case 's':
+ iw = iwinfo_backend(argv[1]);
- default:
- fprintf(stderr, "Unknown command: %s\n", argv[2]);
+ if (!iw)
+ {
+ fprintf(stderr, "No such wireless device: %s\n", argv[1]);
rv = 1;
+ goto finish;
}
+
+ print_scanlist(iw, argv[1], atoi(argv[3]));
+ break;
+
+ default:
+ fprintf(stderr, "Unknown command: %s\n", argv[2]);
+ rv = 1;
}
}
else
@@ -872,7 +899,7 @@ int main(int argc, char **argv)
break;
case 's':
- print_scanlist(iw, argv[1]);
+ print_scanlist(iw, argv[1], 0);
break;
case 't':
@@ -903,6 +930,8 @@ int main(int argc, char **argv)
}
}
+finish:
+
iwinfo_finish();
return rv;
@@ -2083,7 +2083,7 @@ static int nl80211_get_scanlist_cb(struct nl_msg *msg, void *arg)
return NL_SKIP;
}
-static int nl80211_get_scanlist_nl(const char *ifname, char *buf, int *len)
+static int nl80211_get_scanlist_nl(const char *ifname, char *buf, int *len, unsigned int freq)
{
struct nl80211_msg_conveyor *req;
struct nl80211_scanlist sl = { .e = (struct iwinfo_scanlist_entry *)buf };
@@ -2091,6 +2091,17 @@ static int nl80211_get_scanlist_nl(const char *ifname, char *buf, int *len)
req = nl80211_msg(ifname, NL80211_CMD_TRIGGER_SCAN, 0);
if (req)
{
+ if (freq)
+ {
+ struct nlattr *freqs;
+ freqs = nla_nest_start(req->msg, NL80211_ATTR_SCAN_FREQUENCIES);
+ if (!freqs)
+ return -1;
+ if (nla_put_u32(req->msg, 1, freq))
+ return -1;
+ nla_nest_end(req->msg, freqs);
+ }
+
nl80211_send(req, NULL, NULL);
nl80211_free(req);
}
@@ -2298,7 +2309,7 @@ static int nl80211_get_scanlist_wpactl(const char *ifname, char *buf, int *len)
return (count >= 0) ? 0 : -1;
}
-static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
+static int nl80211_get_scanlist2(const char *ifname, char *buf, int *len, unsigned int freq)
{
char *res;
int rv, mode;
@@ -2311,13 +2322,13 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
/* Reuse existing interface */
if ((res = nl80211_phy2ifname(ifname)) != NULL)
{
- return nl80211_get_scanlist(res, buf, len);
+ return nl80211_get_scanlist2(res, buf, len, freq);
}
/* Need to spawn a temporary iface for scanning */
else if ((res = nl80211_ifadd(ifname)) != NULL)
{
- rv = nl80211_get_scanlist(res, buf, len);
+ rv = nl80211_get_scanlist2(res, buf, len, freq);
nl80211_ifdel(res);
return rv;
}
@@ -2337,7 +2348,7 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
mode == IWINFO_OPMODE_MONITOR) &&
iwinfo_ifup(ifname))
{
- return nl80211_get_scanlist_nl(ifname, buf, len);
+ return nl80211_get_scanlist_nl(ifname, buf, len, freq);
}
/* AP scan */
@@ -2349,7 +2360,7 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
if (!iwinfo_ifup(ifname))
return -1;
- rv = nl80211_get_scanlist_nl(ifname, buf, len);
+ rv = nl80211_get_scanlist_nl(ifname, buf, len, freq);
iwinfo_ifdown(ifname);
return rv;
}
@@ -2366,7 +2377,7 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
* additional interface and there's no need to tear down the ap */
if (iwinfo_ifup(res))
{
- rv = nl80211_get_scanlist_nl(res, buf, len);
+ rv = nl80211_get_scanlist_nl(res, buf, len, freq);
iwinfo_ifdown(res);
}
@@ -2374,7 +2385,7 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
* during scan */
else if (iwinfo_ifdown(ifname) && iwinfo_ifup(res))
{
- rv = nl80211_get_scanlist_nl(res, buf, len);
+ rv = nl80211_get_scanlist_nl(res, buf, len, freq);
iwinfo_ifdown(res);
iwinfo_ifup(ifname);
nl80211_hostapd_hup(ifname);
@@ -2388,6 +2399,11 @@ static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
return -1;
}
+static int nl80211_get_scanlist(const char *ifname, char *buf, int *len)
+{
+ return nl80211_get_scanlist2(ifname, buf, len, 0);
+}
+
static int nl80211_get_freqlist_cb(struct nl_msg *msg, void *arg)
{
int bands_remain, freqs_remain;
@@ -2814,6 +2830,7 @@ const struct iwinfo_ops nl80211_ops = {
.assoclist = nl80211_get_assoclist,
.txpwrlist = nl80211_get_txpwrlist,
.scanlist = nl80211_get_scanlist,
+ .scanlist2 = nl80211_get_scanlist2,
.freqlist = nl80211_get_freqlist,
.countrylist = nl80211_get_countrylist,
.lookup_phy = nl80211_lookup_phyname,
Sometimes it is enough to scan single channel only. This is much faster than scanning all of them and ingnoring unnecessary data. Signed-off-by: Dmitry Ivanov <dima@ubnt.com> --- include/iwinfo.h | 1 + iwinfo_cli.c | 65 ++++++++++++++++++++++++++++++++++++++++---------------- iwinfo_nl80211.c | 33 +++++++++++++++++++++------- 3 files changed, 73 insertions(+), 26 deletions(-)