diff options
author | Jens Georg <mail@jensge.org> | 2021-07-04 14:35:03 +0200 |
---|---|---|
committer | Jens Georg <mail@jensge.org> | 2021-07-04 14:35:48 +0200 |
commit | e46ad6757e2396f45385a54e2ad9fbf1a36d2b60 (patch) | |
tree | e2e6bf7e26ff4f9f48ece9802fe82bda1e17416f | |
parent | e2ba94f7e78833f78b7fafd420a046f3c8100ffb (diff) | |
download | gssdp-e46ad6757e2396f45385a54e2ad9fbf1a36d2b60.tar.gz |
win32: Add MAC lookup
This bumps the windows requirement to Vista
-rw-r--r-- | build-aux/getipnettable2-test.c | 24 | ||||
-rw-r--r-- | libgssdp/gssdp-net-win32.c | 69 | ||||
-rw-r--r-- | 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') |