diff options
author | Jonathan McCrohan <jmccrohan@gmail.com> | 2012-03-05 22:35:04 +0000 |
---|---|---|
committer | Jonathan McCrohan <jmccrohan@gmail.com> | 2012-03-05 22:35:04 +0000 |
commit | 28954c917ff9ccc3cb6b79ce39b1d6c7841da13d (patch) | |
tree | 166eafef53933e8d30fdc704cf605319531b1134 /iw_if.c | |
parent | 8f6b56b71ccee4eb800a5b1aa1edbbfb0a0cb6b4 (diff) | |
parent | 89de95a89953c20349a8c7c4684eba45feb34bf5 (diff) | |
download | wavemon-28954c917ff9ccc3cb6b79ce39b1d6c7841da13d.tar.gz |
Merge tag 'upstream/0.7.4'
Upstream version 0.7.4
Diffstat (limited to 'iw_if.c')
-rw-r--r-- | iw_if.c | 49 |
1 files changed, 29 insertions, 20 deletions
@@ -94,39 +94,45 @@ void if_getinf(const char *ifname, struct if_info *info) close(skfd); } -static FILE *open_proc_net(const char *filename) -{ - char path[128]; - FILE *fp; - - snprintf(path, sizeof(path), "/proc/net/%s", filename); - if (access(path, F_OK) != 0) - err_quit("'%s' not accessible - not compiled in?", path); - - fp = fopen(path, "r"); - if (fp == NULL) - err_sys("can not open %s", path); - - return fp; -} - /** * iw_get_interface_list - Return NULL-terminated array of WiFi interfaces. + * Use the safe route of checking /proc/net/dev/ for wireless interfaces: + * - SIOCGIFCONF only returns running interfaces that have an IP address; + * - /proc/net/wireless may exist, but may not list all wireless interfaces. */ char **iw_get_interface_list(void) { char **if_list = NULL, *p, tmp[BUFSIZ]; int nifs = 1; /* if_list[nifs-1] = NULL */ - FILE *fp = open_proc_net("wireless"); + struct iwreq wrq; + FILE *fp; + int skfd = socket(AF_INET, SOCK_DGRAM, 0); + + if (skfd < 0) + err_sys("%s: can not open socket", __func__); + + fp = fopen("/proc/net/dev", "r"); + if (fp == NULL) + err_sys("can not open /proc/net/dev"); - while (fgets(tmp, sizeof(tmp), fp)) + while (fgets(tmp, sizeof(tmp), fp)) { if ((p = strchr(tmp, ':'))) { - if_list = realloc(if_list, sizeof(char *) * (nifs + 1)); for (*p = '\0', p = tmp; isspace(*p); ) p++; + /* + * Use SIOCGIWNAME as indicator: if interface does not + * support this ioctl, it has no wireless extensions. + */ + strncpy(wrq.ifr_name, p, IFNAMSIZ); + if (ioctl(skfd, SIOCGIWNAME, &wrq) < 0) + continue; + + if_list = realloc(if_list, sizeof(char *) * (nifs + 1)); if_list[nifs-1] = strdup(p); if_list[nifs++] = NULL; } + } + close(skfd); fclose(fp); return if_list; } @@ -136,8 +142,11 @@ void if_getstat(const char *ifname, struct if_stat *stat) char line[0x100]; unsigned long d; char *lp; - FILE *fp = open_proc_net("dev"); + const char path[] = "/proc/net/dev"; + FILE *fp = fopen(path, "r"); + if (fp == NULL) + err_sys("can not open %s", path); /* * Inter-| Receive | Transmit * face |bytes packets errs drop fifo frame compressed multicast|bytes packets |