summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Georg <mail@jensge.org>2021-07-04 14:35:03 +0200
committerJens Georg <mail@jensge.org>2021-07-04 14:35:48 +0200
commite46ad6757e2396f45385a54e2ad9fbf1a36d2b60 (patch)
treee2e6bf7e26ff4f9f48ece9802fe82bda1e17416f
parente2ba94f7e78833f78b7fafd420a046f3c8100ffb (diff)
downloadgssdp-e46ad6757e2396f45385a54e2ad9fbf1a36d2b60.tar.gz
win32: Add MAC lookup
This bumps the windows requirement to Vista
-rw-r--r--build-aux/getipnettable2-test.c24
-rw-r--r--libgssdp/gssdp-net-win32.c69
-rw-r--r--meson.build5
3 files changed, 95 insertions, 3 deletions
diff --git a/build-aux/getipnettable2-test.c b/build-aux/getipnettable2-test.c
new file mode 100644
index 0000000..e803dce
--- /dev/null
+++ b/build-aux/getipnettable2-test.c
@@ -0,0 +1,24 @@
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+#include <winsock2.h>
+#include <ws2ipdef.h>
+#include <iphlpapi.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main ()
+{
+ PMIB_IPNET_TABLE2 pipTable = NULL;
+ // MIB_IPNET_ROW2 ipRow;
+
+ unsigned long status = GetIpNetTable2 (AF_INET, &pipTable);
+ if (status != NO_ERROR) {
+ printf ("GetIpNetTable for IPv4 table returned error: %ld\n",
+ status);
+ }
+ FreeMibTable (pipTable);
+}
diff --git a/libgssdp/gssdp-net-win32.c b/libgssdp/gssdp-net-win32.c
index af0a303..3341878 100644
--- a/libgssdp/gssdp-net-win32.c
+++ b/libgssdp/gssdp-net-win32.c
@@ -7,7 +7,9 @@
*
*/
-#define _WIN32_WINNT 0x502
+#define _WIN32_WINNT 0x601
+#include <config.h>
+
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
@@ -96,9 +98,70 @@ gssdp_net_query_ifindex (GSSDPNetworkDevice *device)
char *
gssdp_net_mac_lookup (GSSDPNetworkDevice *device, const char *ip_address)
{
- /* TODO: Is there a way to make this work? */
- /* GetIpNetTable / GetIpNetTable2 for Vista (ipv6) */
+#ifdef HAVE_GETIPNETTABLE2
+ char *result = NULL;
+ GInetAddress *address = g_inet_address_new_from_string (ip_address);
+
+ PMIB_IPNET_TABLE2 pipTable = NULL;
+
+ unsigned long rc = 0;
+ GSocketFamily family = g_inet_address_get_family (address);
+ rc = GetIpNetTable2 (family, &pipTable);
+ if (rc != NO_ERROR) {
+ g_object_unref (address);
+ g_warning (
+ "Failed to GetIpNetTable2 for %s: %s",
+ g_enum_to_string (g_socket_family_get_type (), family),
+ g_win32_error_message (WSAGetLastError ()));
+ return g_strdup (ip_address);
+ }
+
+ for (guint i = 0; i < pipTable->NumEntries; i++) {
+ GInetAddress *adapter_address;
+ if (family == G_SOCKET_FAMILY_IPV4) {
+ adapter_address = g_inet_address_new_from_bytes (
+ (guint8 *) &pipTable->Table[i]
+ .Address.Ipv4.sin_addr,
+ family);
+ } else {
+ adapter_address = g_inet_address_new_from_bytes (
+ (guint8 *) &pipTable->Table[i]
+ .Address.Ipv6.sin6_addr,
+ family);
+ }
+ char *ip = g_inet_address_to_string (adapter_address);
+ if (!g_inet_address_equal (address, adapter_address)) {
+ g_object_unref (adapter_address);
+ continue;
+ }
+ g_free (ip);
+
+ if (pipTable->Table[i].PhysicalAddressLength == 0) {
+ result = g_strdup (ip_address);
+ break;
+ }
+ gssize j;
+ GString *mac_str = g_string_new ("");
+ for (j = 0; j < pipTable->Table[i].PhysicalAddressLength; j++) {
+ if (j > 0) {
+ g_string_append_c (mac_str, ':');
+ }
+ g_string_append_printf (
+ mac_str,
+ "%02x",
+ pipTable->Table[i].PhysicalAddress[j]);
+ }
+
+ result = g_string_free (mac_str, FALSE);
+ break;
+ }
+ g_clear_pointer (&pipTable, FreeMibTable);
+ g_object_unref (address);
+
+ return result;
+#else
return g_strdup (ip_address);
+#endif
}
gboolean
diff --git a/meson.build b/meson.build
index debb900..8ea7d30 100644
--- a/meson.build
+++ b/meson.build
@@ -36,10 +36,15 @@ siocgifindex_available = cc.compiles(siocgifindex_test,
name : 'SIOCGIFINDEX is available')
conf.set('HAVE_SIOCGIFINDEX', siocgifindex_available)
+getipnettable2_available = cc.compiles(files('build-aux/getipnettable2-test.c'), args: '-liphlpapi', name: 'GetIpNetTable2 is available')
+conf.set('HAVE_GETIPNETTABLE2', getipnettable2_available)
+
+
glib_version = '2.54'
conf.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_@0@'.format(glib_version.underscorify()))
conf.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_@0@'.format(glib_version.underscorify()))
+
# Generate config.h, so all config has to be set up until here
subdir('internal')