]> The Tcpdump Group git mirrors - libpcap/commitdiff
Don't assume that device entries in /sys/class/net aren't directories.
authorGuy Harris <[email protected]>
Sun, 2 Dec 2012 04:46:31 +0000 (20:46 -0800)
committerGuy Harris <[email protected]>
Sun, 2 Dec 2012 04:47:14 +0000 (20:47 -0800)
They're directories in older kernels, and symlinks to directories in
newer kernels.  Instead, check whether there's a "subsystem" entry
underneath them.  Ignore "." and "..", and also ignore plain files (as
there's nothing underneath plain files).

pcap-linux.c

index f7d92c04471b401bbcbd4e712b3414663498688b..c641fba9234ba9a8d9646cecce0a36402e3d2f52 100644 (file)
@@ -1953,6 +1953,8 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
        DIR *sys_class_net_d;
        int fd;
        struct dirent *ent;
+       char subsystem_path[PATH_MAX+1];
+       struct stat statb;
        char *p;
        char name[512]; /* XXX - pick a size */
        char *q, *saveq;
@@ -1997,11 +1999,32 @@ scan_sys_class_net(pcap_if_t **devlistp, char *errbuf)
                }
 
                /*
-                * Ignore directories (".", "..", and any subdirectories).
+                * Ignore "." and "..".
                 */
-               if (ent->d_type == DT_DIR)
+               if (strcmp(ent->d_name, ".") == 0 ||
+                   strcmp(ent->d_name, "..") == 0)
                        continue;
 
+               /*
+                * Ignore plain files.
+                */
+               if (ent->d_type == DT_REG)
+                       continue;
+
+               /*
+                * Is there a "subsystem" file under that name?
+                * (We don't care whether it's a directory or
+                * a symlink; older kernels have directories
+                * for devices, newer kernels have symlinks to
+                * directories.)
+                */
+               snprintf(subsystem_path, sizeof subsystem_path,
+                   "/sys/class/net/%s/subsystem", ent->d_name);
+               if (lstat(subsystem_path, &statb) != 0) {
+                       /* Stat failed, ignore */
+                       continue;
+               }
+
                /*
                 * Get the interface name.
                 */