Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iwinfo: generic improvement of assoclist handling #19

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/iwinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,13 @@ struct iwinfo_ops {
int (*hardware_name)(const char *, char *);
int (*encryption)(const char *, char *);
int (*phyname)(const char *, char *);
/*
* assoclist might receive a NULL buf as second element.
* In such case assoclist should only return the length
* of the expected buffer.
* Third element is always set to the size of the buffer.
* assoclist should stop parsing elements if this is reached.
*/
int (*assoclist)(const char *, char *, int *);
int (*txpwrlist)(const char *, char *, int *);
int (*scanlist)(const char *, char *, int *);
Expand Down
29 changes: 25 additions & 4 deletions iwinfo_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,12 +784,12 @@ static void print_freqlist(const struct iwinfo_ops *iw, const char *ifname)

static void print_assoclist(const struct iwinfo_ops *iw, const char *ifname)
{
int i, len;
char buf[IWINFO_BUFSIZE];
int i, len = 0;
char *buf = NULL;
struct iwinfo_assoclist_entry *e;

if (iw->assoclist(ifname, buf, &len))
{
/* Call assoclist with NULL buf to get number of element to alloc */
if (iw->assoclist(ifname, NULL, &len)) {
printf("No information available\n");
return;
}
Expand All @@ -799,6 +799,24 @@ static void print_assoclist(const struct iwinfo_ops *iw, const char *ifname)
return;
}

buf = malloc(len * sizeof(*e));
if (!buf) {
printf("No space to allocate assoc elements buf\n");
return;
}

/* Pass to assoclist the size of buf allocated with len */
if (iw->assoclist(ifname, buf, &len))
{
printf("No information available\n");
goto exit;
}
else if (len <= 0)
{
printf("No station connected\n");
goto exit;
}

for (i = 0; i < len; i += sizeof(struct iwinfo_assoclist_entry))
{
e = (struct iwinfo_assoclist_entry *) &buf[i];
Expand All @@ -823,6 +841,9 @@ static void print_assoclist(const struct iwinfo_ops *iw, const char *ifname)
printf(" expected throughput: %s\n\n",
format_rate(e->thr));
}

exit:
free(buf);
}


Expand Down
9 changes: 9 additions & 0 deletions iwinfo_madwifi.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,14 @@ static int madwifi_get_assoclist(const char *ifname, char *buf, int *len)
do {
si = (struct ieee80211req_sta_info *) cp;

/* If buf is NULL, we only count the station */
if (!buf)
goto next;

/* stop parsing more elements as we reached max buf */
if (bl + sizeof(entry) > *len)
break;

memset(&entry, 0, sizeof(entry));

entry.signal = (si->isi_rssi - 95);
Expand All @@ -797,6 +805,7 @@ static int madwifi_get_assoclist(const char *ifname, char *buf, int *len)

memcpy(&buf[bl], &entry, sizeof(struct iwinfo_assoclist_entry));

next:
bl += sizeof(struct iwinfo_assoclist_entry);
cp += si->isi_len;
tl -= si->isi_len;
Expand Down
20 changes: 19 additions & 1 deletion iwinfo_nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -2254,6 +2254,14 @@ static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
};

/* With NULL buf, we just count the stations */
if (!arr->buf)
goto exit;

/* stop parsing more elements as we reached max buf */
if (arr->count >= arr->max)
return NL_STOP;

/* advance to end of array */
e += arr->count;
memset(e, 0, sizeof(*e));
Expand Down Expand Up @@ -2369,6 +2377,8 @@ static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
}

e->noise = 0; /* filled in by caller */

exit:
arr->count++;

return NL_SKIP;
Expand Down Expand Up @@ -2397,6 +2407,13 @@ static int nl80211_get_assoclist(const char *ifname, char *buf, int *len)
struct nl80211_array_buf arr = { .buf = buf, .count = 0 };
struct iwinfo_assoclist_entry *e;

/* If len is not set, use IWINFO_BUFSIZE by default */
if (!*len)
*len = IWINFO_BUFSIZE;

/* Limit element to the preallocated space */
arr.max = *len / sizeof(*e);

if ((d = opendir("/sys/class/net")) != NULL)
{
while ((de = readdir(d)) != NULL)
Expand All @@ -2412,7 +2429,8 @@ static int nl80211_get_assoclist(const char *ifname, char *buf, int *len)

closedir(d);

if (!nl80211_get_noise(ifname, &noise))
/* Skip setting noise if we are just counting station */
if (arr.buf && !nl80211_get_noise(ifname, &noise))
for (i = 0, e = arr.buf; i < arr.count; i++, e++)
e->noise = noise;

Expand Down
1 change: 1 addition & 0 deletions iwinfo_nl80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct nl80211_rssi_rate {
struct nl80211_array_buf {
void *buf;
int count;
int max;
};

#endif