diff options
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 |