[gssdp] win32: Add MAC lookup



commit e46ad6757e2396f45385a54e2ad9fbf1a36d2b60
Author: Jens Georg <mail jensge org>
Date:   Sun Jul 4 14:35:03 2021 +0200

    win32: Add MAC lookup
    
    This bumps the windows requirement to Vista

 build-aux/getipnettable2-test.c | 24 ++++++++++++++
 libgssdp/gssdp-net-win32.c      | 69 +++++++++++++++++++++++++++++++++++++++--
 meson.build                     |  5 +++
 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')
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]