aboutsummaryrefslogtreecommitdiffstats
path: root/iw_if.c
diff options
context:
space:
mode:
Diffstat (limited to 'iw_if.c')
-rw-r--r--iw_if.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/iw_if.c b/iw_if.c
index 708ff85..8a635f6 100644
--- a/iw_if.c
+++ b/iw_if.c
@@ -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