mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-14 22:38:34 +00:00
(Xbox) Provide implementation function for inet_ntop_compat
This commit is contained in:
parent
be367138f6
commit
dd351a3501
@ -372,12 +372,163 @@ struct in_addr6_compat
|
||||
unsigned char ip_addr[16];
|
||||
};
|
||||
|
||||
#ifdef _XBOX
|
||||
|
||||
#ifndef IM_IN6ADDRSZ
|
||||
#define IM_IN6ADDRSZ 16
|
||||
#endif
|
||||
|
||||
#ifndef IM_INT16SZ
|
||||
#define IM_INT16SZ 2
|
||||
#endif
|
||||
|
||||
#ifndef IM_INADDRSZ
|
||||
#define IM_INADDRSZ 4
|
||||
#endif
|
||||
/* Taken from https://github.com/skywind3000/easenet/blob/master/inetbase.c
|
||||
*/
|
||||
|
||||
/* convert presentation format to network format */
|
||||
static const char *
|
||||
inet_ntop4x(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
char tmp[64];
|
||||
size_t len = snprintf(tmp,
|
||||
sizeof(tmp),
|
||||
"%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
|
||||
|
||||
if (len >= size)
|
||||
goto error;
|
||||
|
||||
memcpy(dst, tmp, len + 1);
|
||||
return dst;
|
||||
|
||||
error:
|
||||
errno = ENOSPC;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* convert presentation format to network format */
|
||||
static const char *
|
||||
inet_ntop6x(const unsigned char *src, char *dst, size_t size)
|
||||
{
|
||||
char tmp[64], *tp;
|
||||
int i, inc;
|
||||
struct { int base, len; } best, cur;
|
||||
unsigned int words[IM_IN6ADDRSZ / IM_INT16SZ];
|
||||
|
||||
memset(words, '\0', sizeof(words));
|
||||
best.base = best.len = 0;
|
||||
cur.base = cur.len = 0;
|
||||
|
||||
for (i = 0; i < IM_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
|
||||
for (i = 0; i < (IM_IN6ADDRSZ / IM_INT16SZ); i++)
|
||||
{
|
||||
if (words[i] == 0)
|
||||
{
|
||||
if (cur.base == -1)
|
||||
{
|
||||
cur.base = i;
|
||||
cur.len = 1;
|
||||
}
|
||||
else cur.len++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cur.base != -1)
|
||||
{
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1)
|
||||
{
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
tp = tmp;
|
||||
for (i = 0; i < (IM_IN6ADDRSZ / IM_INT16SZ); i++)
|
||||
{
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len))
|
||||
{
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
|
||||
{
|
||||
if (!inet_ntop4x(src+12, tp, sizeof(tmp) - (tp - tmp)))
|
||||
return NULL;
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
inc = sprintf(tp, "%x", words[i]);
|
||||
tp += inc;
|
||||
}
|
||||
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(IM_IN6ADDRSZ / IM_INT16SZ))
|
||||
*tp++ = ':';
|
||||
|
||||
*tp++ = '\0';
|
||||
|
||||
if ((size_t)(tp - tmp) > size)
|
||||
goto error;
|
||||
|
||||
memcpy(dst, tmp, tp - tmp);
|
||||
return dst;
|
||||
|
||||
error:
|
||||
errno = ENOSPC;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* convert network format to presentation format */
|
||||
/* another inet_ntop, supports AF_INET/AF_INET6 */
|
||||
static const char *isockaddr_ntop(int af,
|
||||
const void *src, char *dst, size_t size)
|
||||
{
|
||||
switch (af)
|
||||
{
|
||||
case AF_INET:
|
||||
return inet_ntop4x((const unsigned char*)src, dst, size);
|
||||
#ifdef AF_INET6
|
||||
case AF_INET6:
|
||||
return inet_ntop6x((const unsigned char*)src, dst, size);
|
||||
#endif
|
||||
default:
|
||||
if (af == -6)
|
||||
return inet_ntop6x((const unsigned char*)src, dst, size);
|
||||
errno = EAFNOSUPPORT;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *inet_ntop_compat(int af, const void *src, char *dst, socklen_t cnt)
|
||||
{
|
||||
#if defined(VITA) || defined(__ORBIS__)
|
||||
return sceNetInetNtop(af,src,dst,cnt);
|
||||
#elif defined(WIIU)
|
||||
return inet_ntop(af, src, dst, cnt);
|
||||
#elif defined(_XBOX)
|
||||
return isockaddr_ntop(af, src, dst, cnt);
|
||||
#elif defined(_WIN32)
|
||||
if (af == AF_INET)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user