From 01156b122c1c57bb27b664c6b973a35418b1f86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 31 Jul 2013 14:11:55 +0200 Subject: [PATCH] =?UTF-8?q?GSocket=20=E2=80=93=20Implement=20multicast=20i?= =?UTF-8?q?nterface=20selection=20on=20Windows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://bugzilla.gnome.org/show_bug.cgi?id=697185 --- gio/Makefile.am | 2 +- gio/gnetworking.h.in | 1 + gio/gnetworking.h.win32 | 1 + gio/gsocket.c | 59 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/gio/Makefile.am b/gio/Makefile.am index 33d588532..f861e8b5e 100644 --- a/gio/Makefile.am +++ b/gio/Makefile.am @@ -316,7 +316,7 @@ win32_more_sources_for_vcproj = \ if OS_WIN32 appinfo_sources += gwin32appinfo.c gwin32appinfo.h -platform_libadd += -lshlwapi -lws2_32 -ldnsapi +platform_libadd += -lshlwapi -lws2_32 -ldnsapi -liphlpapi win32_sources = $(win32_actual_sources) giowin32includedir=$(includedir)/gio-win32-2.0/gio diff --git a/gio/gnetworking.h.in b/gio/gnetworking.h.in index 99bdadd53..a1d471600 100644 --- a/gio/gnetworking.h.in +++ b/gio/gnetworking.h.in @@ -34,6 +34,7 @@ #include #include @WSPIAPI_INCLUDE@ +#include #else /* !G_OS_WIN32 */ diff --git a/gio/gnetworking.h.win32 b/gio/gnetworking.h.win32 index c6e11a4a6..c5a898009 100644 --- a/gio/gnetworking.h.win32 +++ b/gio/gnetworking.h.win32 @@ -34,6 +34,7 @@ #include #include #include +#include #else /* !G_OS_WIN32 */ diff --git a/gio/gsocket.c b/gio/gsocket.c index a1b00a347..b60617146 100644 --- a/gio/gsocket.c +++ b/gio/gsocket.c @@ -1934,6 +1934,60 @@ g_socket_bind (GSocket *socket, return TRUE; } +#if !defined(HAVE_IF_NAMETOINDEX) && defined(G_OS_WIN32) +static guint +if_nametoindex (const gchar *iface) +{ + PIP_ADAPTER_ADDRESSES addresses = NULL, p; + gulong addresses_len = 0; + guint idx = 0; + DWORD res; + + res = GetAdaptersAddresses (AF_UNSPEC, 0, NULL, NULL, &addresses_len); + if (res != NO_ERROR && res != ERROR_BUFFER_OVERFLOW) + { + if (res == ERROR_NO_DATA) + errno = ENXIO; + else + errno = EINVAL; + return 0; + } + + addresses = g_malloc (addresses_len); + res = GetAdaptersAddresses (AF_UNSPEC, 0, NULL, addresses, &addresses_len); + + if (res != NO_ERROR) + { + g_free (addresses); + if (res == ERROR_NO_DATA) + errno = ENXIO; + else + errno = EINVAL; + return 0; + } + + p = addresses; + while (p) + { + if (strcmp (p->AdapterName, iface) == 0) + { + idx = p->IfIndex; + break; + } + p = p->Next; + } + + if (p == NULL) + errno = ENXIO; + + g_free (addresses); + + return idx; +} + +#define HAVE_IF_NAMETOINDEX 1 +#endif + static gboolean g_socket_multicast_group_operation (GSocket *socket, GInetAddress *group, @@ -1969,6 +2023,11 @@ g_socket_multicast_group_operation (GSocket *socket, mc_req.imr_ifindex = if_nametoindex (iface); else mc_req.imr_ifindex = 0; /* Pick any. */ +#elif defined(G_OS_WIN32) + if (iface) + mc_req.imr_interface.s_addr = g_htonl (if_nametoindex (iface)); + else + mc_req.imr_interface.s_addr = g_htonl (INADDR_ANY); #else mc_req.imr_interface.s_addr = g_htonl (INADDR_ANY); #endif