[Olsr-dev] [PATCH v1 8/9] ifnet: add getInterfaceLinkState function

Ferry Huberts (spam-protected)
Wed Feb 10 14:35:47 CET 2016


From: Ferry Huberts <(spam-protected)>

This Linux-only function queries a network interface to see if it has a
carrier (cable (dis)connected, medium up/down, etc).

Signed-off-by: Ferry Huberts <(spam-protected)>
---
 src/ifnet.h      | 12 ++++++++++++
 src/unix/ifnet.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

diff --git a/src/ifnet.h b/src/ifnet.h
index 3bc1dd7..fa22f17 100644
--- a/src/ifnet.h
+++ b/src/ifnet.h
@@ -62,6 +62,18 @@ int chk_if_up(struct olsr_if *, int);
 
 int add_hemu_if(struct olsr_if *);
 
+typedef enum {
+  LINKSTATE_UNKNOWN, LINKSTATE_UP, LINKSTATE_DOWN
+} LinkState;
+
+#if defined(__linux__) && !defined(__ANDROID__)
+  LinkState getInterfaceLinkState(const char * iface);
+#else
+  static INLINE LinkState getInterfaceLinkState(__attribute__((unused)) const char * iface) {
+    return LINKSTATE_UNKNOWN;
+  }
+#endif /* defined(__linux__) && !defined(__ANDROID__) */
+
 #endif /* _OLSR_IFNET */
 
 /*
diff --git a/src/unix/ifnet.c b/src/unix/ifnet.c
index c1055ec..e475b9d 100644
--- a/src/unix/ifnet.c
+++ b/src/unix/ifnet.c
@@ -69,6 +69,10 @@
 #include <arpa/inet.h>
 #include <netdb.h>
 #include <unistd.h>
+#if defined(__linux__) && !defined(__ANDROID__)
+#include <linux/ethtool.h>
+#include <linux/sockios.h>
+#endif /* defined(__linux__) && !defined(__ANDROID__) */
 
 /**
  * Fix bug in GLIBC, see https://bugzilla.redhat.com/show_bug.cgi?id=635260
@@ -836,6 +840,44 @@ chk_if_up(struct olsr_if *iface, int debuglvl __attribute__ ((unused)))
   return 1;
 }
 
+#if defined(__linux__) && !defined(__ANDROID__)
+LinkState getInterfaceLinkState(const char * iface) {
+  LinkState r = LINKSTATE_UNKNOWN;
+  int fd;
+  struct ethtool_value edata;
+  struct ifreq ifr;
+
+  if (!iface) {
+    return r;
+  }
+
+  memset(&ifr, 0, sizeof(ifr));
+
+  fd = socket(AF_INET, SOCK_DGRAM, 0);
+  if (fd < 0) {
+    return r;
+  }
+
+  edata.cmd = ETHTOOL_GLINK;
+  strcpy(ifr.ifr_name, iface);
+  ifr.ifr_data = (caddr_t) &edata;
+  errno = 0;
+  if (!ioctl(fd, SIOCETHTOOL, &ifr)) {
+    /* ioctl success */
+    r = edata.data ? LINKSTATE_UP : LINKSTATE_DOWN;
+  } else if (errno == EOPNOTSUPP) {
+    /* no kernel support */
+    r = LINKSTATE_UNKNOWN;
+  } else {
+    /* other error */
+    r = LINKSTATE_UNKNOWN;
+  }
+
+  close(fd);
+  return r;
+}
+#endif /* defined(__linux__) && !defined(__ANDROID__) */
+
 /*
  * Local Variables:
  * c-basic-offset: 2
-- 
2.5.0




More information about the Olsr-dev mailing list