summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-07-09 09:24:47 (GMT)
committerMarcel Holtmann <marcel@holtmann.org>2012-07-09 12:30:50 (GMT)
commitdebd3f4f9865fdd5a998a3845c42fb1d415ceef6 (patch)
treee5dc5bd0d750ab45d8f5164a95057c28d1b45786
parent2c1534b97872f83538684a72f8876012f78da7e6 (diff)
downloadconnman-debd3f4f9865fdd5a998a3845c42fb1d415ceef6.zip
connman-debd3f4f9865fdd5a998a3845c42fb1d415ceef6.tar.gz
connman-debd3f4f9865fdd5a998a3845c42fb1d415ceef6.tar.bz2
inet: Return all running interfaces
Add a function that returns all (except loopback) interfaces that are up and running (have IP address). This information is used in following patch to clean up the routes that are left hanging around.
-rw-r--r--src/connman.h1
-rw-r--r--src/inet.c78
2 files changed, 79 insertions, 0 deletions
diff --git a/src/connman.h b/src/connman.h
index 5ab9eb5..6726078 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -133,6 +133,7 @@ void __connman_task_cleanup(void);
#include <connman/inet.h>
+char **__connman_inet_get_running_interfaces(void);
int __connman_inet_modify_address(int cmd, int flags, int index, int family,
const char *address,
const char *peer,
diff --git a/src/inet.c b/src/inet.c
index 7208d4e..c28c3e4 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -2238,3 +2238,81 @@ connman_bool_t connman_inet_check_hostname(const char *ptr, size_t len)
return TRUE;
}
+
+char **__connman_inet_get_running_interfaces(void)
+{
+ char **result;
+ struct ifconf ifc;
+ struct ifreq *ifr = NULL;
+ int sk, i, numif, count = 0;
+
+ memset(&ifc, 0, sizeof(ifc));
+
+ sk = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sk < 0)
+ return NULL;
+
+ if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
+ goto error;
+
+ /*
+ * Allocate some extra bytes just in case there will
+ * be new interfaces added between two SIOCGIFCONF
+ * calls.
+ */
+ ifr = g_try_malloc0(ifc.ifc_len * 2);
+ if (ifr == NULL)
+ goto error;
+
+ ifc.ifc_req = ifr;
+
+ if (ioctl(sk, SIOCGIFCONF, &ifc) < 0)
+ goto error;
+
+ numif = ifc.ifc_len / sizeof(struct ifreq);
+
+ result = g_try_malloc0((numif + 1) * sizeof(char *));
+ if (result == NULL)
+ goto error;
+
+ close(sk);
+
+ for (i = 0; i < numif; i++) {
+ struct ifreq *r = &ifr[i];
+ struct in6_addr *addr6;
+ in_addr_t addr4;
+
+ /*
+ * Note that we do not return loopback interfaces here as they
+ * are not needed for our purposes.
+ */
+ switch (r->ifr_addr.sa_family) {
+ case AF_INET:
+ addr4 = ntohl(((struct sockaddr_in *)
+ &r->ifr_addr)->sin_addr.s_addr);
+ if (((addr4 & 0xff000000) >> 24) == 127)
+ continue;
+ break;
+ case AF_INET6:
+ addr6 = &((struct sockaddr_in6 *)
+ &r->ifr_addr)->sin6_addr;
+ if (IN6_IS_ADDR_LINKLOCAL(addr6))
+ continue;
+ break;
+ }
+
+ result[count++] = g_strdup(r->ifr_name);
+ }
+
+ free(ifr);
+
+ if (count < numif)
+ result = g_try_realloc(result, (count + 1) * sizeof(char *));
+
+ return result;
+
+error:
+ close(sk);
+ free(ifr);
+ return NULL;
+}