mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 13:20:30 +00:00
(Network) net_ifinfo refactor (#14102)
This commit is contained in:
parent
a7dc57f68f
commit
14e5cd317b
@ -20,10 +20,9 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LIBRETRO_NET_IFINFO_H
|
||||
#define _LIBRETRO_NET_IFINFO_H
|
||||
#ifndef _LIBRETRO_SDK_NET_IFINFO_H
|
||||
#define _LIBRETRO_SDK_NET_IFINFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <boolean.h>
|
||||
@ -34,22 +33,20 @@ RETRO_BEGIN_DECLS
|
||||
|
||||
struct net_ifinfo_entry
|
||||
{
|
||||
char *name;
|
||||
char *host;
|
||||
char name[256];
|
||||
char host[256];
|
||||
};
|
||||
|
||||
struct net_ifinfo
|
||||
typedef struct net_ifinfo
|
||||
{
|
||||
struct net_ifinfo_entry *entries;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
typedef struct net_ifinfo net_ifinfo_t;
|
||||
|
||||
void net_ifinfo_free(net_ifinfo_t *list);
|
||||
} net_ifinfo_t;
|
||||
|
||||
bool net_ifinfo_new(net_ifinfo_t *list);
|
||||
|
||||
void net_ifinfo_free(net_ifinfo_t *list);
|
||||
|
||||
bool net_ifinfo_best(const char *dst, void *src, bool ipv6);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
@ -20,274 +20,287 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <retro_miscellaneous.h>
|
||||
#include <string/stdstring.h>
|
||||
#include <net/net_compat.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "Iphlpapi")
|
||||
#endif
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#include <ws2tcpip.h>
|
||||
#elif defined (GEKKO) && !defined(WIIU)
|
||||
#include <network.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#ifdef WANT_IFADDRS
|
||||
#elif !defined(GEKKO)
|
||||
#if defined(WANT_IFADDRS)
|
||||
#include <compat/ifaddrs.h>
|
||||
#else
|
||||
#if !defined HAVE_LIBNX && !defined(_3DS)
|
||||
#elif !defined(HAVE_LIBNX) && !defined(_3DS)
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <net/net_ifinfo.h>
|
||||
|
||||
#if defined(BSD)
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
void net_ifinfo_free(net_ifinfo_t *list)
|
||||
{
|
||||
unsigned k;
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
for (k = 0; k < list->size; k++)
|
||||
{
|
||||
struct net_ifinfo_entry *ptr =
|
||||
(struct net_ifinfo_entry*)&list->entries[k];
|
||||
|
||||
if (*ptr->name)
|
||||
free(ptr->name);
|
||||
if (*ptr->host)
|
||||
free(ptr->host);
|
||||
|
||||
ptr->name = NULL;
|
||||
ptr->host = NULL;
|
||||
}
|
||||
free(list->entries);
|
||||
}
|
||||
|
||||
#if defined(HAVE_LIBNX) || defined(_3DS) || defined(GEKKO)
|
||||
static void convert_ip(char *dst, size_t size, uint32_t ip, bool inverted)
|
||||
{
|
||||
unsigned char bytes[4];
|
||||
bytes[0] = ip & 0xFF;
|
||||
bytes[1] = (ip >> 8) & 0xFF;
|
||||
bytes[2] = (ip >> 16) & 0xFF;
|
||||
bytes[3] = (ip >> 24) & 0xFF;
|
||||
|
||||
if (inverted)
|
||||
snprintf(dst, size, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3]);
|
||||
else
|
||||
snprintf(dst, size, "%d.%d.%d.%d", bytes[3], bytes[2], bytes[1], bytes[0]);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool net_ifinfo_new(net_ifinfo_t *list)
|
||||
{
|
||||
#if defined(GEKKO)
|
||||
char hostname[128];
|
||||
#if defined(_WIN32) && !defined(_XBOX)
|
||||
/* Microsoft docs recommend doing it this way. */
|
||||
char buf[512];
|
||||
ULONG result;
|
||||
PIP_ADAPTER_ADDRESSES addr;
|
||||
struct net_ifinfo_entry *entry;
|
||||
size_t interfaces = 0;
|
||||
ULONG flags = GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
|
||||
ULONG len = 15 * 1024;
|
||||
PIP_ADAPTER_ADDRESSES addresses = (PIP_ADAPTER_ADDRESSES)calloc(1, len);
|
||||
|
||||
memset(list, 0, sizeof(net_ifinfo_t));
|
||||
list->entries = NULL;
|
||||
|
||||
/* loopback */
|
||||
list->entries = (struct net_ifinfo_entry*)
|
||||
malloc(2 * sizeof(struct net_ifinfo_entry));
|
||||
if (!addresses)
|
||||
goto failure;
|
||||
|
||||
if (!list->entries)
|
||||
goto error;
|
||||
|
||||
list->entries[0].name = strdup("lo");
|
||||
list->entries[0].host = strdup("127.0.0.1");
|
||||
list->entries[1].name = strdup("gekko");
|
||||
convert_ip(hostname, sizeof(hostname), net_gethostip(), false);
|
||||
list->entries[1].host = strdup(hostname);
|
||||
list->size = 2;
|
||||
|
||||
return true;
|
||||
|
||||
/*
|
||||
actual interface
|
||||
can be wlan or eth (with a wiiu adapter)
|
||||
so we just use "switch" as a name
|
||||
*/
|
||||
#elif defined(HAVE_LIBNX) || defined(_3DS)
|
||||
uint32_t id;
|
||||
#ifdef HAVE_LIBNX
|
||||
Result rc;
|
||||
#endif
|
||||
char hostname[128];
|
||||
unsigned k = 0;
|
||||
struct net_ifinfo_entry *ptr = NULL;
|
||||
|
||||
memset(list, 0, sizeof(net_ifinfo_t));
|
||||
|
||||
/* loopback */
|
||||
convert_ip(hostname, sizeof(hostname), INADDR_LOOPBACK, false);
|
||||
|
||||
ptr = (struct net_ifinfo_entry*)
|
||||
realloc(list->entries, (k+1) * sizeof(struct net_ifinfo_entry));
|
||||
|
||||
if (!ptr)
|
||||
goto error;
|
||||
|
||||
list->entries = ptr;
|
||||
|
||||
list->entries[k].name = strdup("lo");
|
||||
list->entries[k].host = strdup(hostname);
|
||||
list->size = k + 1;
|
||||
|
||||
k++;
|
||||
|
||||
/*
|
||||
actual interface
|
||||
can be wlan or eth (with a wiiu adapter)
|
||||
so we just use "switch" as a name
|
||||
*/
|
||||
#if defined(_3DS) || defined (GEKKO)
|
||||
convert_ip(hostname, sizeof(hostname), gethostid(), true);
|
||||
#else
|
||||
rc = nifmGetCurrentIpAddress(&id);
|
||||
|
||||
if (!R_SUCCEEDED(rc)) /* not connected to any network */
|
||||
return true;
|
||||
|
||||
convert_ip(hostname, sizeof(hostname), id, true);
|
||||
#endif
|
||||
|
||||
ptr = (struct net_ifinfo_entry*)
|
||||
realloc(list->entries, (k+1) * sizeof(struct net_ifinfo_entry));
|
||||
|
||||
if (!ptr)
|
||||
goto error;
|
||||
|
||||
list->entries = ptr;
|
||||
#if defined(_3DS)
|
||||
list->entries[k].name = strdup("wlan");
|
||||
#else
|
||||
list->entries[k].name = strdup("switch");
|
||||
#endif
|
||||
list->entries[k].host = strdup(hostname);
|
||||
list->size = k + 1;
|
||||
|
||||
return true;
|
||||
#elif defined(_WIN32) && !defined(_XBOX)
|
||||
unsigned k = 0;
|
||||
PIP_ADAPTER_ADDRESSES adapter_addresses = NULL, aa = NULL;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS ua = NULL;
|
||||
#ifdef _WIN32_WINNT_WINXP
|
||||
DWORD size = 0;
|
||||
DWORD rv = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &size);
|
||||
adapter_addresses = (PIP_ADAPTER_ADDRESSES)malloc(size);
|
||||
rv = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL, adapter_addresses, &size);
|
||||
|
||||
memset(list, 0, sizeof(net_ifinfo_t));
|
||||
|
||||
if (rv != ERROR_SUCCESS)
|
||||
goto error;
|
||||
#endif
|
||||
for (aa = adapter_addresses; aa != NULL; aa = aa->Next)
|
||||
result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, addresses, &len);
|
||||
if (result == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
char name[PATH_MAX_LENGTH];
|
||||
memset(name, 0, sizeof(name));
|
||||
PIP_ADAPTER_ADDRESSES new_addresses =
|
||||
(PIP_ADAPTER_ADDRESSES)realloc(addresses, len);
|
||||
|
||||
WideCharToMultiByte(CP_UTF8, 0, aa->FriendlyName, wcslen(aa->FriendlyName),
|
||||
name, PATH_MAX_LENGTH, NULL, NULL);
|
||||
|
||||
for (ua = aa->FirstUnicastAddress; ua != NULL; ua = ua->Next)
|
||||
if (new_addresses)
|
||||
{
|
||||
char host[PATH_MAX_LENGTH];
|
||||
struct net_ifinfo_entry *ptr = (struct net_ifinfo_entry*)
|
||||
realloc(list->entries, (k+1) * sizeof(struct net_ifinfo_entry));
|
||||
memset(new_addresses, 0, len);
|
||||
|
||||
if (!ptr)
|
||||
goto error;
|
||||
|
||||
list->entries = ptr;
|
||||
|
||||
memset(host, 0, sizeof(host));
|
||||
|
||||
getnameinfo(ua->Address.lpSockaddr, ua->Address.iSockaddrLength,
|
||||
host, sizeof(host), NULL, NI_MAXSERV, NI_NUMERICHOST);
|
||||
|
||||
list->entries[k].name = strdup(name);
|
||||
list->entries[k].host = strdup(host);
|
||||
list->size = k + 1;
|
||||
|
||||
k++;
|
||||
addresses = new_addresses;
|
||||
result = GetAdaptersAddresses(AF_UNSPEC, flags, NULL,
|
||||
addresses, &len);
|
||||
}
|
||||
}
|
||||
if (result != ERROR_SUCCESS)
|
||||
goto failure;
|
||||
|
||||
free(adapter_addresses);
|
||||
#else
|
||||
unsigned k = 0;
|
||||
struct ifaddrs *ifa = NULL;
|
||||
struct ifaddrs *ifaddr = NULL;
|
||||
/* Count the number of valid interfaces first. */
|
||||
addr = addresses;
|
||||
|
||||
memset(list, 0, sizeof(net_ifinfo_t));
|
||||
|
||||
if (getifaddrs(&ifaddr) == -1)
|
||||
goto error;
|
||||
|
||||
if (!list)
|
||||
goto error;
|
||||
|
||||
for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
|
||||
do
|
||||
{
|
||||
char host[NI_MAXHOST];
|
||||
struct net_ifinfo_entry *ptr = NULL;
|
||||
PIP_ADAPTER_UNICAST_ADDRESS unicast_addr = addr->FirstUnicastAddress;
|
||||
|
||||
if (!ifa->ifa_addr)
|
||||
if (!unicast_addr)
|
||||
continue;
|
||||
if (addr->OperStatus != IfOperStatusUp)
|
||||
continue;
|
||||
|
||||
if (ifa->ifa_addr->sa_family != AF_INET)
|
||||
do
|
||||
{
|
||||
interfaces++;
|
||||
} while ((unicast_addr = unicast_addr->Next));
|
||||
} while ((addr = addr->Next));
|
||||
|
||||
if (!interfaces)
|
||||
goto failure;
|
||||
|
||||
list->entries =
|
||||
(struct net_ifinfo_entry*)calloc(interfaces, sizeof(*list->entries));
|
||||
if (!list->entries)
|
||||
goto failure;
|
||||
list->size = 0;
|
||||
|
||||
/* Now create the entries. */
|
||||
addr = addresses;
|
||||
entry = list->entries;
|
||||
|
||||
do
|
||||
{
|
||||
PIP_ADAPTER_UNICAST_ADDRESS unicast_addr = addr->FirstUnicastAddress;
|
||||
|
||||
if (!unicast_addr)
|
||||
continue;
|
||||
if (addr->OperStatus != IfOperStatusUp)
|
||||
continue;
|
||||
|
||||
if (getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in),
|
||||
host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0)
|
||||
goto error;
|
||||
buf[0] = '\0';
|
||||
if (addr->FriendlyName)
|
||||
{
|
||||
if (!WideCharToMultiByte(CP_UTF8, 0, addr->FriendlyName, -1,
|
||||
buf, sizeof(buf), NULL, NULL))
|
||||
buf[0] = '\0'; /* Empty name on conversion failure. */
|
||||
}
|
||||
|
||||
ptr = (struct net_ifinfo_entry*)
|
||||
realloc(list->entries, (k+1) * sizeof(struct net_ifinfo_entry));
|
||||
do
|
||||
{
|
||||
if (getnameinfo(unicast_addr->Address.lpSockaddr,
|
||||
unicast_addr->Address.iSockaddrLength,
|
||||
entry->host, sizeof(entry->host), NULL, 0, NI_NUMERICHOST))
|
||||
continue;
|
||||
|
||||
if (!ptr)
|
||||
goto error;
|
||||
strlcpy(entry->name, buf, sizeof(entry->name));
|
||||
|
||||
list->entries = ptr;
|
||||
if (++list->size >= interfaces)
|
||||
break;
|
||||
|
||||
list->entries[k].name = strdup(ifa->ifa_name);
|
||||
list->entries[k].host = strdup(host);
|
||||
list->size = k + 1;
|
||||
entry++;
|
||||
} while ((unicast_addr = unicast_addr->Next));
|
||||
|
||||
k++;
|
||||
}
|
||||
if (list->size >= interfaces)
|
||||
break;
|
||||
} while ((addr = addr->Next));
|
||||
|
||||
free(addresses);
|
||||
|
||||
freeifaddrs(ifaddr);
|
||||
#endif
|
||||
return true;
|
||||
|
||||
error:
|
||||
#ifdef _WIN32
|
||||
if (adapter_addresses)
|
||||
free(adapter_addresses);
|
||||
#elif !defined(HAVE_LIBNX) && !defined(_3DS) && !defined(GEKKO)
|
||||
freeifaddrs(ifaddr);
|
||||
#endif
|
||||
failure:
|
||||
free(addresses);
|
||||
net_ifinfo_free(list);
|
||||
|
||||
return false;
|
||||
#elif defined(HAVE_LIBNX) || defined(_3DS) || defined(GEKKO)
|
||||
uint32_t addr = 0;
|
||||
|
||||
list->entries = (struct net_ifinfo_entry*)calloc(2, sizeof(*list->entries));
|
||||
if (!list->entries)
|
||||
{
|
||||
list->size = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
strcpy_literal(list->entries[0].name, "lo");
|
||||
strcpy_literal(list->entries[0].host, "127.0.0.1");
|
||||
list->size = 1;
|
||||
|
||||
#if defined(HAVE_LIBNX)
|
||||
{
|
||||
Result rc = nifmGetCurrentIpAddress(&addr);
|
||||
|
||||
if (!R_SUCCEEDED(rc))
|
||||
return true;
|
||||
}
|
||||
#elif defined(_3DS)
|
||||
addr = gethostid();
|
||||
#else
|
||||
addr = net_gethostip();
|
||||
#endif
|
||||
if (addr)
|
||||
{
|
||||
uint8_t *addr8 = (uint8_t*)&addr;
|
||||
|
||||
strcpy_literal(list->entries[1].name,
|
||||
#if defined(HAVE_LIBNX)
|
||||
"switch"
|
||||
#elif defined(_3DS)
|
||||
"wlan"
|
||||
#else
|
||||
"gekko"
|
||||
#endif
|
||||
);
|
||||
snprintf(list->entries[1].host, sizeof(list->entries[1].host),
|
||||
"%d.%d.%d.%d",
|
||||
(int)addr8[0], (int)addr8[1], (int)addr8[2], (int)addr8[3]);
|
||||
list->size++;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
struct ifaddrs *addr;
|
||||
struct net_ifinfo_entry *entry;
|
||||
size_t interfaces = 0;
|
||||
struct ifaddrs *addresses = NULL;
|
||||
|
||||
list->entries = NULL;
|
||||
|
||||
if (getifaddrs(&addresses) || !addresses)
|
||||
goto failure;
|
||||
|
||||
/* Count the number of valid interfaces first. */
|
||||
addr = addresses;
|
||||
|
||||
do
|
||||
{
|
||||
if (!addr->ifa_addr)
|
||||
continue;
|
||||
if (!(addr->ifa_flags & IFF_UP))
|
||||
continue;
|
||||
|
||||
switch (addr->ifa_addr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
interfaces++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while ((addr = addr->ifa_next));
|
||||
|
||||
if (!interfaces)
|
||||
goto failure;
|
||||
|
||||
list->entries =
|
||||
(struct net_ifinfo_entry*)calloc(interfaces, sizeof(*list->entries));
|
||||
if (!list->entries)
|
||||
goto failure;
|
||||
list->size = 0;
|
||||
|
||||
/* Now create the entries. */
|
||||
addr = addresses;
|
||||
entry = list->entries;
|
||||
|
||||
do
|
||||
{
|
||||
socklen_t addrlen;
|
||||
|
||||
if (!addr->ifa_addr)
|
||||
continue;
|
||||
if (!(addr->ifa_flags & IFF_UP))
|
||||
continue;
|
||||
|
||||
switch (addr->ifa_addr->sa_family)
|
||||
{
|
||||
case AF_INET:
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
break;
|
||||
case AF_INET6:
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getnameinfo(addr->ifa_addr, addrlen,
|
||||
entry->host, sizeof(entry->host), NULL, 0, NI_NUMERICHOST))
|
||||
continue;
|
||||
|
||||
if (addr->ifa_name)
|
||||
strlcpy(entry->name, addr->ifa_name, sizeof(entry->name));
|
||||
|
||||
if (++list->size >= interfaces)
|
||||
break;
|
||||
|
||||
entry++;
|
||||
} while ((addr = addr->ifa_next));
|
||||
|
||||
freeifaddrs(addresses);
|
||||
|
||||
return true;
|
||||
|
||||
failure:
|
||||
freeifaddrs(addresses);
|
||||
net_ifinfo_free(list);
|
||||
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void net_ifinfo_free(net_ifinfo_t *list)
|
||||
{
|
||||
free(list->entries);
|
||||
|
||||
list->entries = NULL;
|
||||
list->size = 0;
|
||||
}
|
||||
|
||||
bool net_ifinfo_best(const char *dst, void *src, bool ipv6)
|
||||
@ -300,42 +313,40 @@ bool net_ifinfo_best(const char *dst, void *src, bool ipv6)
|
||||
{
|
||||
/* Courtesy of MiniUPnP: https://github.com/miniupnp/miniupnp */
|
||||
DWORD index;
|
||||
unsigned long udst = inet_addr(dst);
|
||||
#ifdef __WINRT__
|
||||
struct sockaddr_in addr_dst = {0};
|
||||
struct sockaddr_in dst_addr = {0};
|
||||
#endif
|
||||
|
||||
if (udst == INADDR_NONE || udst == INADDR_ANY)
|
||||
return ret;
|
||||
IPAddr dst_ip = inet_addr(dst);
|
||||
|
||||
if (!src)
|
||||
return ret;
|
||||
return false;
|
||||
if (dst_ip == INADDR_NONE || dst_ip == INADDR_ANY)
|
||||
return false;
|
||||
|
||||
#ifdef __WINRT__
|
||||
addr_dst.sin_family = AF_INET;
|
||||
addr_dst.sin_addr.s_addr = udst;
|
||||
if (GetBestInterfaceEx((struct sockaddr *) &addr_dst, &index)
|
||||
== NO_ERROR)
|
||||
dst_addr.sin_family = AF_INET;
|
||||
dst_addr.sin_addr.s_addr = dst_ip;
|
||||
if (GetBestInterfaceEx((struct sockaddr*)&dst_addr, &index) == NO_ERROR)
|
||||
#else
|
||||
if (GetBestInterface(udst, &index) == NO_ERROR)
|
||||
if (GetBestInterface(dst_ip, &index) == NO_ERROR)
|
||||
#endif
|
||||
{
|
||||
/* Microsoft docs recommend doing it this way. */
|
||||
ULONG len = 15 * 1024;
|
||||
PIP_ADAPTER_ADDRESSES addresses = (PIP_ADAPTER_ADDRESSES)calloc(1, len);
|
||||
ULONG len = 15 * 1024;
|
||||
PIP_ADAPTER_ADDRESSES addresses =
|
||||
(PIP_ADAPTER_ADDRESSES)calloc(1, len);
|
||||
|
||||
if (addresses)
|
||||
{
|
||||
ULONG flags = GAA_FLAG_SKIP_ANYCAST |
|
||||
GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER |
|
||||
GAA_FLAG_SKIP_FRIENDLY_NAME;
|
||||
ULONG flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |
|
||||
GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME;
|
||||
ULONG result = GetAdaptersAddresses(AF_INET, flags, NULL,
|
||||
addresses, &len);
|
||||
|
||||
if (result == ERROR_BUFFER_OVERFLOW)
|
||||
{
|
||||
PIP_ADAPTER_ADDRESSES new_addresses = (PIP_ADAPTER_ADDRESSES)realloc(addresses, len);
|
||||
PIP_ADAPTER_ADDRESSES new_addresses =
|
||||
(PIP_ADAPTER_ADDRESSES)realloc(addresses, len);
|
||||
|
||||
if (new_addresses)
|
||||
{
|
||||
@ -358,8 +369,8 @@ bool net_ifinfo_best(const char *dst, void *src, bool ipv6)
|
||||
if (addr->FirstUnicastAddress)
|
||||
{
|
||||
struct sockaddr_in *addr_unicast =
|
||||
(struct sockaddr_in *)
|
||||
addr->FirstUnicastAddress->Address.lpSockaddr;
|
||||
(struct sockaddr_in*)
|
||||
addr->FirstUnicastAddress->Address.lpSockaddr;
|
||||
|
||||
memcpy(src, &addr_unicast->sin_addr,
|
||||
sizeof(addr_unicast->sin_addr));
|
||||
|
Loading…
x
Reference in New Issue
Block a user