[farsight2/master] Import interface finding code from Farsight1
Olivier Crête
olivier.crete at collabora.co.uk
Tue Dec 23 15:19:30 PST 2008
---
configure.ac | 2 +
transmitters/rawudp/fs-interfaces.c | 369 +++++++++++++++++++++++++++++++++++
transmitters/rawudp/fs-interfaces.h | 31 +++
3 files changed, 402 insertions(+), 0 deletions(-)
create mode 100644 transmitters/rawudp/fs-interfaces.c
create mode 100644 transmitters/rawudp/fs-interfaces.h
diff --git a/configure.ac b/configure.ac
index 6f3ec55..a85af7b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -266,6 +266,8 @@ echo
fi dnl of EXT plugins
+AC_CHECK_FUNCS(getifaddrs)
+
dnl *** finalize CFLAGS, LDFLAGS, LIBS
dnl Overview:
diff --git a/transmitters/rawudp/fs-interfaces.c b/transmitters/rawudp/fs-interfaces.c
new file mode 100644
index 0000000..935f232
--- /dev/null
+++ b/transmitters/rawudp/fs-interfaces.c
@@ -0,0 +1,369 @@
+/*
+ * farsight-interfaces.c - Source for interface discovery code
+ *
+ * Farsight Helper functions
+ * Copyright (C) 2006 Youness Alaoui <kakaroto at kakaroto.homelinux.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "fs-interfaces.h"
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+
+#ifdef G_OS_UNIX
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#ifdef HAVE_GETIFADDRS
+#include <sys/socket.h>
+#include <ifaddrs.h>
+#endif
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <arpa/inet.h>
+
+/**
+ * farsight_get_local_interfaces:
+ *
+ * Get the list of local interfaces
+ *
+ * Returns: a #GList of strings.
+ */
+#ifdef HAVE_GETIFADDRS
+GList * farsight_get_local_interfaces() {
+ GList *interfaces = NULL;
+ struct ifaddrs *ifa, *results;
+
+ if (getifaddrs(&results) < 0) {
+ if (errno == ENOMEM)
+ return NULL;
+ else
+ return NULL;
+ }
+
+ /* Loop and get each interface the system has, one by one... */
+ for (ifa = results; ifa; ifa = ifa->ifa_next) {
+ /* no ip address from interface that is down */
+ if ((ifa->ifa_flags & IFF_UP) == 0)
+ continue;
+
+ if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+
+ g_debug("Found interface : %s", ifa->ifa_name);
+ interfaces = g_list_prepend(interfaces, g_strdup(ifa->ifa_name));
+ }
+
+ return interfaces;
+}
+
+#else
+GList * farsight_get_local_interfaces() {
+ GList *interfaces = NULL;
+ gint sockfd;
+ gint size = 0;
+ struct ifreq *ifr;
+ struct ifconf ifc;
+
+ if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
+ g_warning("Cannot open socket to retreive interface list");
+ return NULL;
+ }
+
+ ifc.ifc_len = 0;
+ ifc.ifc_req = NULL;
+
+ /* Loop and get each interface the system has, one by one... */
+ do {
+ size += sizeof(struct ifreq);
+ /* realloc buffer size until no overflow occurs */
+ if (NULL == (ifc.ifc_req = realloc(ifc.ifc_req, size))) {
+ g_warning ("Out of memory while allocation interface configuration structure");
+ close(sockfd);
+ return NULL;
+ }
+ ifc.ifc_len = size;
+
+ if (ioctl(sockfd, SIOCGIFCONF, &ifc)) {
+ perror("ioctl SIOCFIFCONF");
+ close(sockfd);
+ return NULL;
+ }
+ } while (size <= ifc.ifc_len);
+
+
+ /* Loop throught the interface list and get the IP address of each IF */
+ for (ifr = ifc.ifc_req;(gchar *) ifr < (gchar *) ifc.ifc_req + ifc.ifc_len; ++ifr) {
+ g_debug("Found interface : %s", ifr->ifr_name);
+ interfaces = g_list_prepend(interfaces, g_strdup(ifr->ifr_name));
+ }
+
+ close(sockfd);
+
+ return interfaces;
+}
+#endif
+
+
+static gboolean farsight_is_private_ip (const struct in_addr in)
+{
+ if (in.s_addr >> 24 == 0x0A) /* 10.x.x.x/8 */
+ return TRUE;
+
+ if (in.s_addr >> 22 == 0x2B0) /* 172.16.0.0 - 172.31.255.255 = 172.16.0.0/10 */
+ return TRUE;
+
+ if (in.s_addr >> 16 == 0xc0A8) /* 192.168.x.x/16 */
+ return TRUE;
+
+ if (in.s_addr >> 16 == 0xA9FE) /* 169.254.x.x/16 (for APIPA) */
+ return TRUE;
+
+
+ return FALSE;
+}
+
+/**
+ * farsight_get_local_ips:
+ * @include_loopback: Include any loopback devices
+ *
+ * Get a list of local ip4 interface addresses
+ *
+ * Returns: A #GList of strings
+ */
+#ifdef HAVE_GETIFADDRS
+GList * farsight_get_local_ips(gboolean include_loopback)
+{
+ GList *ips = NULL;
+ struct sockaddr_in *sa;
+ struct ifaddrs *ifa, *results;
+
+
+ if (getifaddrs(&results) < 0) {
+ if (errno == ENOMEM)
+ return NULL;
+ else
+ return NULL;
+ }
+
+ /* Loop through the interface list and get the IP address of each IF */
+ for (ifa = results; ifa; ifa = ifa->ifa_next) {
+ /* no ip address from interface that is down */
+ if ((ifa->ifa_flags & IFF_UP) == 0)
+ continue;
+
+ if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
+ continue;
+
+ sa = (struct sockaddr_in *) ifa->ifa_addr;
+
+ g_debug("Interface: %s", ifa->ifa_name);
+ g_debug("IP Address: %s", inet_ntoa(sa->sin_addr));
+ if ( !include_loopback && (ifa->ifa_flags & IFF_LOOPBACK) == IFF_LOOPBACK) {
+ g_debug("Ignoring loopback interface");
+ } else {
+ if (farsight_is_private_ip (sa->sin_addr)) {
+ ips = g_list_append(ips, g_strdup(inet_ntoa(sa->sin_addr)));
+ } else {
+ ips = g_list_prepend(ips, g_strdup(inet_ntoa(sa->sin_addr)));
+ }
+ }
+ }
+
+ return ips;
+}
+
+#else
+
+GList * farsight_get_local_ips(gboolean include_loopback)
+{
+ GList *ips = NULL;
+ gint sockfd;
+ gint size = 0;
+ struct ifreq *ifr;
+ struct ifconf ifc;
+ struct sockaddr_in *sa;
+
+ if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
+ g_warning("Cannot open socket to retreive interface list");
+ return NULL;
+ }
+
+ ifc.ifc_len = 0;
+ ifc.ifc_req = NULL;
+
+ /* Loop and get each interface the system has, one by one... */
+ do {
+ size += sizeof(struct ifreq);
+ /* realloc buffer size until no overflow occurs */
+ if (NULL == (ifc.ifc_req = realloc(ifc.ifc_req, size))) {
+ g_warning ("Out of memory while allocation interface configuration structure");
+ close(sockfd);
+ return NULL;
+ }
+ ifc.ifc_len = size;
+
+ if (ioctl(sockfd, SIOCGIFCONF, &ifc)) {
+ perror("ioctl SIOCFIFCONF");
+ close(sockfd);
+ return NULL;
+ }
+ } while (size <= ifc.ifc_len);
+
+
+ /* Loop throught the interface list and get the IP address of each IF */
+ for (ifr = ifc.ifc_req;(gchar *) ifr < (gchar *) ifc.ifc_req + ifc.ifc_len; ++ifr) {
+
+ if (ioctl(sockfd, SIOCGIFFLAGS, ifr)) {
+ g_warning("Unable to get IP information for interface %s. Skipping...", ifr->ifr_name);
+ continue; /* failed to get flags, skip it */
+ }
+ sa = (struct sockaddr_in *) &ifr->ifr_addr;
+ g_debug("Interface: %s", ifr->ifr_name);
+ g_debug("IP Address: %s", inet_ntoa(sa->sin_addr));
+ if ( !include_loopback && (ifr->ifr_flags & IFF_LOOPBACK) == IFF_LOOPBACK) {
+ g_debug("Ignoring loopback interface");
+ } else {
+ if (farsight_is_private_ip (sa->sin_addr)) {
+ ips = g_list_append(ips, g_strdup(inet_ntoa(sa->sin_addr)));
+ } else {
+ ips = g_list_prepend(ips, g_strdup(inet_ntoa(sa->sin_addr)));
+ }
+ }
+ }
+
+ close(sockfd);
+
+ return ips;
+}
+#endif
+
+
+/**
+ * farsight_get_ip_for_interface:
+ * @interface_name: name of local interface
+ *
+ * Retreives the IP Address of an interface by its name
+ *
+ * Returns:
+ **/
+gchar * farsight_get_ip_for_interface(gchar *interface_name) {
+ struct ifreq ifr;
+ struct sockaddr_in *sa;
+ gint sockfd;
+
+
+ ifr.ifr_addr.sa_family = AF_INET;
+ memset(ifr.ifr_name, 0, sizeof(ifr.ifr_name));
+ strcpy(ifr.ifr_name, interface_name);
+
+ if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
+ g_warning("Cannot open socket to retreive interface list");
+ return NULL;
+ }
+
+ if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) {
+ g_warning("Unable to get IP information for interface %s",interface_name );
+ close(sockfd);
+ return NULL;
+ }
+
+ close(sockfd);
+ sa = (struct sockaddr_in *) &ifr.ifr_addr;
+ g_debug("Address for %s: %s", interface_name, inet_ntoa(sa->sin_addr));
+ return inet_ntoa(sa->sin_addr);
+}
+
+#else /* G_OS_UNIX */
+#ifdef G_OS_WIN32
+
+#include <windows.h>
+#include <winsock.h>
+
+static gboolean started_wsa_engine = FALSE;
+
+#error Windows support is not yet implemented
+
+/**
+ * private function that initializes the WinSock engine and returns a prebuilt socket
+ **/
+SOCKET farsight_get_WSA_socket() {
+
+ WORD wVersionRequested;
+ WSADATA wsaData;
+ int err;
+ SOCKET sock;
+
+ if (started_wsa_engine == FALSE) {
+ wVersionRequested = MAKEWORD( 2, 0 );
+
+ err = WSAStartup( wVersionRequested, &wsaData );
+ if ( err != 0 ) {
+ g_warning("Could not start the winsocket engine");
+ return INVALID_SOCKET;
+ }
+ started_wsa_engine = TRUE;
+ }
+
+
+ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
+ g_warning("Could not open socket to retreive interface list, error no : %d", WSAGetLastError());
+ return INVALID_SOCKET;
+ }
+
+ return sock;
+}
+
+/**
+ * Returns the list of local interfaces
+ **/
+GList * farsight_get_local_interfaces()
+{
+ return NULL;
+}
+
+
+/**
+ * Returns the list of local ips
+ **/
+GList * farsight_get_local_ips()
+{
+ return NULL;
+}
+
+/**
+ * retreives the IP Address of an interface by its name
+ **/
+gchar * farsight_get_ip_for_interface(gchar *interface_name)
+{
+ return NULL;
+
+}
+
+
+#else /* G_OS_WIN32 */
+#error Can\'t use this method for retreiving ip list from OS other than unix or windows
+#endif /* G_OS_WIN32 */
+#endif /* G_OS_UNIX */
diff --git a/transmitters/rawudp/fs-interfaces.h b/transmitters/rawudp/fs-interfaces.h
new file mode 100644
index 0000000..2aaa7c3
--- /dev/null
+++ b/transmitters/rawudp/fs-interfaces.h
@@ -0,0 +1,31 @@
+/*
+ * farsight-interfaces.h - Source for interface discovery code
+ *
+ * Farsight Helper functions
+ * Copyright (C) 2006 Youness Alaoui <kakaroto at kakaroto.homelinux.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __FARSIGHT_INTERFACES_H_
+#define __FARSIGHT_INTERFACES_H_
+
+#include <glib.h>
+
+gchar * farsight_get_ip_for_interface(gchar *interface_name);
+GList * farsight_get_local_ips(gboolean include_loopback);
+GList * farsight_get_local_interfaces();
+
+#endif
--
1.5.6.5
More information about the farsight-commits
mailing list