From: Guy Harris Date: Sun, 2 Dec 2012 04:46:31 +0000 (-0800) Subject: Don't assume that device entries in /sys/class/net aren't directories. X-Git-Url: https://git.tcpdump.org/libpcap/commitdiff_plain/f6ffc3812e4522b67187bcc2d95aabb0d8d159d6 Don't assume that device entries in /sys/class/net aren't directories. 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). --- diff --git a/pcap-linux.c b/pcap-linux.c index f7d92c04..c641fba9 100644 --- a/pcap-linux.c +++ b/pcap-linux.c @@ -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. */