X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Ffirst_network_device.c;h=93626a266c68ec411c48f971caf557b92a18229d;hb=2d38178063d13dd3a1e477dadb31ebad53a2a471;hp=541aabb4d69daa2cf032b07d7445efb00a71aa3b;hpb=15de209cbaee6827f061e8d2788c9db232012c6b;p=i3%2Fi3status diff --git a/src/first_network_device.c b/src/first_network_device.c index 541aabb..93626a2 100644 --- a/src/first_network_device.c +++ b/src/first_network_device.c @@ -3,9 +3,27 @@ #include #include #include +#if defined(__OpenBSD__) || defined(__DragonFly__) +#include +#include +#include +#include +#endif +#if defined(__OpenBSD__) +#include +#include +#elif defined(__DragonFly__) +#include +#endif #include "i3status.h" +#ifdef __OpenBSD__ +#define LOOPBACK_DEV "lo0" +#else +#define LOOPBACK_DEV "lo" +#endif + static bool sysfs_devtype(char *dest, size_t n, const char *ifnam) { FILE *fp; char buf[1024]; @@ -36,12 +54,89 @@ static bool sysfs_devtype(char *dest, size_t n, const char *ifnam) { return true; } +static bool is_virtual(const char *ifname) { + char path[1024]; + char *target = NULL; + bool is_virtual = false; + + snprintf(path, sizeof(path), "/sys/class/net/%s", ifname); + if ((target = realpath(path, NULL))) { + if (BEGINS_WITH(target, "/sys/devices/virtual/")) { + is_virtual = true; + } + } + + free(target); + return is_virtual; +} + static net_type_t iface_type(const char *ifname) { +#if defined(__OpenBSD__) + /* + *First determine if the device is a wireless device by trying two ioctl(2) + * commands against it. If either succeeds we can be sure it's a wireless + * device. + * Otherwise we try another ioctl(2) to determine the interface media. If that + * fails it's not an ethernet device eiter. + */ + struct ifreq ifr; + struct ieee80211_bssid bssid; + struct ieee80211_nwid nwid; +#elif defined(__DragonFly__) + struct ieee80211req ifr; +#endif +#if defined(__OpenBSD__) || defined(__DragonFly__) + struct ifmediareq ifmr; + int s; +#endif +#if defined(__OpenBSD__) + int ibssid, inwid; +#endif +#if defined(__OpenBSD__) || defined(__DragonFly__) + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + return NET_TYPE_OTHER; + + memset(&ifr, 0, sizeof(ifr)); +#endif +#if defined(__OpenBSD__) + ifr.ifr_data = (caddr_t)&nwid; + (void)strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + inwid = ioctl(s, SIOCG80211NWID, (caddr_t)&ifr); + + memset(&bssid, 0, sizeof(bssid)); + strlcpy(bssid.i_name, ifname, sizeof(bssid.i_name)); + ibssid = ioctl(s, SIOCG80211BSSID, &bssid); + + if (ibssid == 0 || inwid == 0) { + close(s); + return NET_TYPE_WIRELESS; + } +#elif defined(__DragonFly__) + (void)strlcpy(ifr.i_name, ifname, sizeof(ifr.i_name)); + ifr.i_type = IEEE80211_IOC_NUMSSIDS; + if (ioctl(s, SIOCG80211, &ifr) == 0) { + close(s); + return NET_TYPE_WIRELESS; + } +#endif +#if defined(__OpenBSD__) || defined(__DragonFly__) + (void)memset(&ifmr, 0, sizeof(ifmr)); + (void)strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name)); + + if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) { + close(s); + return NET_TYPE_OTHER; + } else { + close(s); + return NET_TYPE_ETHERNET; + } +#else char devtype[32]; if (!sysfs_devtype(devtype, sizeof(devtype), ifname)) return NET_TYPE_OTHER; + /* Default to Ethernet when no devtype is available */ if (!devtype[0]) return NET_TYPE_ETHERNET; @@ -51,6 +146,8 @@ static net_type_t iface_type(const char *ifname) { if (strcmp(devtype, "wwan") == 0) return NET_TYPE_OTHER; + return NET_TYPE_OTHER; +#endif return NET_TYPE_OTHER; } @@ -69,19 +166,26 @@ const char *first_eth_interface(const net_type_t type) { for (addrp = ifaddr; addrp != NULL; addrp = addrp->ifa_next) { - if (strncasecmp("lo", addrp->ifa_name, strlen("lo")) == 0) + if (strncasecmp(LOOPBACK_DEV, addrp->ifa_name, strlen(LOOPBACK_DEV)) == 0) continue; if (addrp->ifa_addr == NULL) continue; +#ifdef __OpenBSD__ + if (addrp->ifa_addr->sa_family != AF_LINK) + continue; +#else // Skip PF_PACKET addresses (MAC addresses), as they are present on any // ethernet interface. if (addrp->ifa_addr->sa_family != AF_INET && addrp->ifa_addr->sa_family != AF_INET6) continue; +#endif /* !__OpenBSD__ */ // Skip this interface if it is a wireless interface. iftype = iface_type(addrp->ifa_name); if (iftype != type) continue; + if (is_virtual(addrp->ifa_name)) + continue; interface = strdup(addrp->ifa_name); break; }