mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 13:47:58 +03:00
685 lines
16 KiB
C
685 lines
16 KiB
C
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
#include "gsPlatformSocket.h"
|
|
#include "gsPlatformUtil.h"
|
|
#include "gsMemory.h"
|
|
|
|
// mj-ToDo: remove these and include the files int the linker instead.
|
|
// removing reference to other platforms.
|
|
// remove all plat specific code from here, move it to the platspecific files.
|
|
|
|
// Include platform separated functions
|
|
#if defined(_X360)
|
|
#include "x360/gsSocketX360.c"
|
|
#elif defined(_XBOX)
|
|
#include "xbox/gsSocketXBox.c"
|
|
#elif defined(_WIN32)
|
|
#include "win32/gsSocketWin32.c"
|
|
#elif defined(_LINUX)
|
|
//#include "linux/gsSocketLinux.c"
|
|
#elif defined(_MACOSX)
|
|
//#include "macosx/gsSocketMacOSX.c"
|
|
#elif defined(_NITRO)
|
|
#include "nitro/gsSocketNitro.c"
|
|
#elif defined(_PS2)
|
|
#include "ps2/gsSocketPs2.c"
|
|
#elif defined(_PS3)
|
|
#include "ps3/gsSocketPs3.c"
|
|
#include <sys/select.h>
|
|
#elif defined(_PSP)
|
|
#include "psp/gsSocketPSP.c"
|
|
#elif defined(_REVOLUTION)
|
|
#include "revolution/gsSocketRevolution.c"
|
|
#else
|
|
#error "Missing or unsupported platform"
|
|
#endif
|
|
|
|
|
|
// Disable compiler warnings for issues that are unavoidable.
|
|
/////////////////////////////////////////////////////////////
|
|
#if defined(_MSC_VER) // DevStudio
|
|
// Level4, "conditional expression is constant".
|
|
// Occurs with use of the MS provided macro FD_SET
|
|
#pragma warning ( disable: 4127 )
|
|
#endif // _MSC_VER
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
int SetSockBlocking(SOCKET sock, int isblocking)
|
|
{
|
|
int rcode;
|
|
|
|
#if defined(_REVOLUTION)
|
|
int val;
|
|
|
|
val = SOFcntl(sock, SO_F_GETFL, 0);
|
|
|
|
if(isblocking)
|
|
val &= ~SO_O_NONBLOCK;
|
|
else
|
|
val |= SO_O_NONBLOCK;
|
|
|
|
rcode = SOFcntl(sock, SO_F_SETFL, val);
|
|
#elif defined(_NITRO)
|
|
int val;
|
|
|
|
val = SOC_Fcntl(sock, SOC_F_GETFL, 0);
|
|
|
|
if(isblocking)
|
|
val &= ~SOC_O_NONBLOCK;
|
|
else
|
|
val |= SOC_O_NONBLOCK;
|
|
|
|
rcode = SOC_Fcntl(sock, SOC_F_SETFL, val);
|
|
#else
|
|
#if defined(_PS2) || defined(_PS3)
|
|
// EENet requires int
|
|
// SNSystems requires int
|
|
// Insock requires int
|
|
// PS3 requires int
|
|
gsi_i32 argp;
|
|
#else
|
|
unsigned long argp;
|
|
#endif
|
|
|
|
if(isblocking)
|
|
argp = 0;
|
|
else
|
|
argp = 1;
|
|
|
|
#ifdef _PS2
|
|
#ifdef SN_SYSTEMS
|
|
rcode = setsockopt(sock, SOL_SOCKET, (isblocking) ? SO_BIO : SO_NBIO, &argp, sizeof(argp));
|
|
#endif
|
|
|
|
#ifdef EENET
|
|
rcode = setsockopt(sock, SOL_SOCKET, SO_NBIO, &argp, sizeof(argp));
|
|
#endif
|
|
|
|
#ifdef INSOCK
|
|
if (isblocking)
|
|
argp = -1;
|
|
else
|
|
argp = 5; //added longer timeout to 5ms
|
|
sceInsockSetRecvTimeout(sock, argp);
|
|
sceInsockSetSendTimeout(sock, argp);
|
|
sceInsockSetShutdownTimeout(sock, argp);
|
|
GSI_UNUSED(sock);
|
|
rcode = 0;
|
|
#endif
|
|
#elif defined(_PSP)
|
|
rcode = setsockopt(sock, SCE_NET_INET_SOL_SOCKET, SCE_NET_INET_SO_NBIO, &argp, sizeof(argp));
|
|
#elif defined(_PS3)
|
|
rcode = setsockopt(sock, SOL_SOCKET, SO_NBIO, &argp, sizeof(argp));
|
|
#else
|
|
rcode = ioctlsocket(sock, FIONBIO, &argp);
|
|
#endif
|
|
#endif
|
|
|
|
if(rcode == 0)
|
|
{
|
|
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment,
|
|
"SetSockBlocking: Set socket %d to %s\r\n", (unsigned int)sock, isblocking ? "blocking":"non-blocking");
|
|
return 1;
|
|
}
|
|
|
|
gsDebugFormat(GSIDebugCat_Common, GSIDebugType_Network, GSIDebugLevel_Comment,
|
|
"SetSockBlocking failed: tried to set socket %d to %s\r\n", (unsigned int)sock, isblocking ? "blocking":"non-blocking");
|
|
return 0;
|
|
}
|
|
|
|
int SetSockBroadcast(SOCKET sock)
|
|
{
|
|
#if !defined(INSOCK) && !defined(_NITRO) && !defined(_REVOLUTION)
|
|
int optval = 1;
|
|
if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&optval, sizeof(optval)) != 0)
|
|
return 0;
|
|
#else
|
|
GSI_UNUSED(sock);
|
|
#endif
|
|
|
|
return 1;
|
|
}
|
|
|
|
int DisableNagle(SOCKET sock)
|
|
{
|
|
#if defined(_WIN32) || defined(_UNIX)
|
|
int rcode;
|
|
int noDelay = 1;
|
|
|
|
rcode = setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&noDelay, sizeof(int));
|
|
return gsiSocketIsError(rcode);
|
|
#else
|
|
GSI_UNUSED(sock);
|
|
|
|
// not supported
|
|
return 0;
|
|
#endif // moved this to here to silence VC warning
|
|
}
|
|
|
|
|
|
#ifndef INSOCK
|
|
int SetReceiveBufferSize(SOCKET sock, int size)
|
|
{
|
|
int rcode;
|
|
rcode = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (const char *)&size, sizeof(int));
|
|
return gsiSocketIsNotError(rcode);
|
|
}
|
|
|
|
int SetSendBufferSize(SOCKET sock, int size)
|
|
{
|
|
int rcode;
|
|
rcode = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char *)&size, sizeof(int));
|
|
return gsiSocketIsNotError(rcode);
|
|
}
|
|
|
|
int GetReceiveBufferSize(SOCKET sock)
|
|
{
|
|
int rcode;
|
|
int size;
|
|
int len;
|
|
|
|
len = sizeof(size);
|
|
|
|
rcode = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&size, &len);
|
|
|
|
if(gsiSocketIsError(rcode))
|
|
return -1;
|
|
|
|
return size;
|
|
}
|
|
|
|
int GetSendBufferSize(SOCKET sock)
|
|
{
|
|
int rcode;
|
|
int size;
|
|
int len;
|
|
|
|
len = sizeof(size);
|
|
|
|
rcode = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&size, &len);
|
|
|
|
if(gsiSocketIsError(rcode))
|
|
return -1;
|
|
|
|
return size;
|
|
}
|
|
|
|
// Formerly known as ghiSocketSelect
|
|
#ifdef SN_SYSTEMS
|
|
#undef FD_SET
|
|
#define FD_SET(s,p) ((p)->array[((s) - 1) >> SN_FD_SHR] |= \
|
|
(unsigned int)(1 << (((s) - 1) & SN_FD_BITS)) )
|
|
|
|
#endif
|
|
#endif
|
|
|
|
#if !defined(_NITRO) && !defined(INSOCK) && !defined(_REVOLUTION)
|
|
int GSISocketSelect(SOCKET theSocket, int* theReadFlag, int* theWriteFlag, int* theExceptFlag)
|
|
{
|
|
fd_set aReadSet;
|
|
fd_set aWriteSet;
|
|
fd_set aExceptSet;
|
|
fd_set * aReadFds = NULL;
|
|
fd_set * aWriteFds = NULL;
|
|
fd_set * aExceptFds = NULL;
|
|
int aResult;
|
|
// 04-13-2005, Saad Nader
|
|
// Added case for SN Systems that would
|
|
// handle errors after performing selects.
|
|
#ifdef SN_SYSTEMS
|
|
int aOut, aOutLen = sizeof(aOut);
|
|
#endif
|
|
|
|
struct timeval aTimeout = { 0, 0 };
|
|
|
|
if (theSocket == INVALID_SOCKET)
|
|
return -1;
|
|
|
|
// Setup the parameters.
|
|
////////////////////////
|
|
if(theReadFlag != NULL)
|
|
{
|
|
FD_ZERO(&aReadSet);
|
|
FD_SET(theSocket,&aReadSet);
|
|
aReadFds = &aReadSet;
|
|
}
|
|
if(theWriteFlag != NULL)
|
|
{
|
|
FD_ZERO(&aWriteSet);
|
|
FD_SET(theSocket, &aWriteSet);
|
|
aWriteFds = &aWriteSet;
|
|
}
|
|
if(theExceptFlag != NULL)
|
|
{
|
|
FD_ZERO(&aExceptSet);
|
|
FD_SET(theSocket, &aExceptSet);
|
|
aExceptFds = &aExceptSet;
|
|
}
|
|
#ifdef _PS3
|
|
// to do, port what is below in the else
|
|
//int socketselect(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
|
|
aResult = socketselect(FD_SETSIZE, aReadFds, aWriteFds, aExceptFds, &aTimeout);
|
|
#else
|
|
// Perform the select
|
|
aResult = select(FD_SETSIZE, aReadFds, aWriteFds, aExceptFds, &aTimeout);
|
|
#endif
|
|
if(gsiSocketIsError(aResult))
|
|
return -1;
|
|
|
|
// 04-13-2005, Saad Nader
|
|
// Added case for SN Systems that would
|
|
// handle errors after performing selects.
|
|
#ifdef SN_SYSTEMS
|
|
getsockopt(theSocket, SOL_SOCKET, SO_ERROR, (char *)&aOut, &aOutLen);
|
|
if (aOut != 0)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
// Check results.
|
|
/////////////////
|
|
if(theReadFlag != NULL)
|
|
{
|
|
if((aResult > 0) && FD_ISSET(theSocket, aReadFds))
|
|
*theReadFlag = 1;
|
|
else
|
|
*theReadFlag = 0;
|
|
}
|
|
if(theWriteFlag != NULL)
|
|
{
|
|
if((aResult > 0) && FD_ISSET(theSocket, aWriteFds))
|
|
*theWriteFlag = 1;
|
|
else
|
|
*theWriteFlag = 0;
|
|
}
|
|
if(theExceptFlag != NULL)
|
|
{
|
|
if((aResult > 0) && FD_ISSET(theSocket, aExceptFds))
|
|
*theExceptFlag = 1;
|
|
else
|
|
*theExceptFlag = 0;
|
|
}
|
|
return aResult; // 0 or 1 at this point
|
|
}
|
|
#endif // !nitro && !revolution && !insock
|
|
|
|
|
|
// Return 1 for immediate recv, otherwise 0
|
|
int CanReceiveOnSocket(SOCKET sock)
|
|
{
|
|
int aReadFlag = 0;
|
|
if (1 == GSISocketSelect(sock, &aReadFlag, NULL, NULL))
|
|
return aReadFlag;
|
|
|
|
// SDKs expect 0 on SOCKET_ERROR
|
|
return 0;
|
|
}
|
|
|
|
// Return 1 for immediate send, otherwise 0
|
|
int CanSendOnSocket(SOCKET sock)
|
|
{
|
|
int aWriteFlag = 0;
|
|
if (1 == GSISocketSelect(sock, NULL, &aWriteFlag, NULL))
|
|
return aWriteFlag;
|
|
|
|
// SDKs expect 0 on SOCKET_ERROR
|
|
return 0;
|
|
}
|
|
|
|
|
|
#if defined(_PS3) || defined (_PSP)
|
|
|
|
#else
|
|
|
|
HOSTENT * getlocalhost(void)
|
|
{
|
|
#ifdef EENET
|
|
#define MAX_IPS 5
|
|
|
|
static HOSTENT localhost;
|
|
static char * aliases = NULL;
|
|
static char * ipPtrs[MAX_IPS + 1];
|
|
static unsigned int ips[MAX_IPS];
|
|
|
|
struct sceEENetIfname * interfaces;
|
|
struct sceEENetIfname * interface;
|
|
int num;
|
|
int i;
|
|
int count;
|
|
int len;
|
|
u_short flags;
|
|
IN_ADDR address;
|
|
|
|
// initialize the host
|
|
localhost.h_name = "localhost";
|
|
localhost.h_aliases = &aliases;
|
|
localhost.h_addrtype = AF_INET;
|
|
localhost.h_length = 0;
|
|
localhost.h_addr_list = ipPtrs;
|
|
|
|
// get the local interfaces
|
|
sceEENetGetIfnames(NULL, &num);
|
|
interfaces = (struct sceEENetIfname *)gsimalloc(num * sizeof(struct sceEENetIfname));
|
|
if(!interfaces)
|
|
return NULL;
|
|
sceEENetGetIfnames(interfaces, &num);
|
|
|
|
// loop through the interfaces
|
|
count = 0;
|
|
for(i = 0 ; i < num ; i++)
|
|
{
|
|
// the next interface
|
|
interface = &interfaces[i];
|
|
//printf("eenet%d: %s\n", i, interface->ifn_name);
|
|
|
|
// get the flags
|
|
len = sizeof(flags);
|
|
if(sceEENetGetIfinfo(interface->ifn_name, sceEENET_IFINFO_IFFLAGS, &flags, &len) != 0)
|
|
continue;
|
|
//printf("eenet%d flags: 0x%X\n", i, flags);
|
|
|
|
// check for up, running, and non-loopback
|
|
if(!(flags & (IFF_UP|IFF_RUNNING)) || (flags & IFF_LOOPBACK))
|
|
continue;
|
|
//printf("eenet%d: up and running, non-loopback\n", i);
|
|
|
|
// get the address
|
|
len = sizeof(address);
|
|
if(sceEENetGetIfinfo(interface->ifn_name, sceEENET_IFINFO_ADDR, &address, &len) != 0)
|
|
continue;
|
|
//printf("eenet%d: %s\n", i, inet_ntoa(address));
|
|
|
|
// add this address
|
|
ips[count] = address.s_addr;
|
|
ipPtrs[count] = (char *)&ips[count];
|
|
count++;
|
|
}
|
|
|
|
// free the interfaces
|
|
gsifree(interfaces);
|
|
|
|
// check that we got at least one IP
|
|
if(!count)
|
|
return NULL;
|
|
|
|
// finish filling in the host struct
|
|
localhost.h_length = (gsi_u16)sizeof(ips[0]);
|
|
ipPtrs[count] = NULL;
|
|
|
|
return &localhost;
|
|
|
|
////////////////////
|
|
// INSOCK
|
|
#elif defined(INSOCK)
|
|
// Global storage
|
|
#define MAX_IPS sceLIBNET_MAX_INTERFACE
|
|
static HOSTENT localhost;
|
|
static char * aliases = NULL;
|
|
static char * ipPtrs[MAX_IPS + 1];
|
|
static unsigned int ips[MAX_IPS];
|
|
|
|
// Temp storage
|
|
int aInterfaceIdArray[MAX_IPS];
|
|
int aNumInterfaces = 0;
|
|
int aInterfaceNum = 0;
|
|
int aCount = 0;
|
|
|
|
// Get the list of interfaces
|
|
aNumInterfaces = sceInetGetInterfaceList(&gGSIInsockClientData,
|
|
&gGSIInsockSocketBuffer, aInterfaceIdArray, MAX_IPS);
|
|
if (aNumInterfaces < 1)
|
|
return NULL;
|
|
|
|
// initialize the HOSTENT
|
|
localhost.h_name = "localhost";
|
|
localhost.h_aliases = &aliases;
|
|
localhost.h_addrtype = AF_INET;
|
|
localhost.h_addr_list = ipPtrs;
|
|
|
|
// Look up each address and copy into the HOSTENT structure
|
|
aCount = 0; // count of valid interfaces
|
|
for (aInterfaceNum = 0; aInterfaceNum < aNumInterfaces; aInterfaceNum++)
|
|
{
|
|
sceInetAddress_t anAddr;
|
|
int result = sceInetInterfaceControl(&gGSIInsockClientData, &gGSIInsockSocketBuffer,
|
|
aInterfaceIdArray[aInterfaceNum], sceInetCC_GetAddress,
|
|
&anAddr, sizeof(anAddr));
|
|
if (result == 0)
|
|
{
|
|
// Add this interface to the array
|
|
memcpy(&ips[aCount], anAddr.data, sizeof(ips[aCount]));
|
|
ips[aCount] = htonl(ips[aCount]);
|
|
ipPtrs[aCount] = (char*)&ips[aCount];
|
|
aCount++;
|
|
}
|
|
}
|
|
|
|
// Set the final hostent data, then return
|
|
localhost.h_length = (gsi_u16)sizeof(ips[0]);
|
|
ipPtrs[aCount] = NULL;
|
|
return &localhost;
|
|
|
|
#elif defined(_NITRO)
|
|
#define MAX_IPS 5
|
|
|
|
static HOSTENT localhost;
|
|
static char * aliases = NULL;
|
|
static char * ipPtrs[MAX_IPS + 1];
|
|
static unsigned int ips[MAX_IPS];
|
|
|
|
int count = 0;
|
|
|
|
localhost.h_name = "localhost";
|
|
localhost.h_aliases = &aliases;
|
|
localhost.h_addrtype = AF_INET;
|
|
localhost.h_length = 0;
|
|
localhost.h_addr_list = (u8 **)ipPtrs;
|
|
|
|
ips[count] = 0;
|
|
IP_GetAddr(NULL, (u8*)&ips[count]);
|
|
if(ips[count] == 0)
|
|
return NULL;
|
|
ipPtrs[count] = (char *)&ips[count];
|
|
count++;
|
|
|
|
localhost.h_length = (gsi_u16)sizeof(ips[0]);
|
|
ipPtrs[count] = NULL;
|
|
|
|
return &localhost;
|
|
|
|
#elif defined(_REVOLUTION)
|
|
#define MAX_IPS 5
|
|
static HOSTENT aLocalHost;
|
|
static char * aliases = NULL;
|
|
int aNumOfIps, i;
|
|
int aSizeNumOfIps;
|
|
static IPAddrEntry aAddrs[MAX_IPS];
|
|
int aAddrsSize, aAddrsSizeInitial;
|
|
static u8 * ipPtrs[MAX_IPS + 1];
|
|
static unsigned int ips[MAX_IPS];
|
|
int ret;
|
|
aSizeNumOfIps = sizeof(aNumOfIps);
|
|
ret = SOGetInterfaceOpt(NULL, SO_SOL_CONFIG, SO_CONFIG_IP_ADDR_NUMBER, &aNumOfIps, &aSizeNumOfIps);
|
|
if (ret != 0)
|
|
return NULL;
|
|
|
|
aAddrsSize = (int)(MAX_IPS * sizeof(IPAddrEntry));
|
|
aAddrsSizeInitial = aAddrsSize;
|
|
ret = SOGetInterfaceOpt(NULL, SO_SOL_CONFIG, SO_CONFIG_IP_ADDR_TABLE, &aAddrs, &aAddrsSize);
|
|
if (ret != 0)
|
|
return NULL;
|
|
|
|
if (aAddrsSize != aAddrsSizeInitial)
|
|
{
|
|
aNumOfIps = aAddrsSize / (int)sizeof(IPAddrEntry);
|
|
}
|
|
|
|
aLocalHost.h_name = "localhost";
|
|
aLocalHost.h_aliases = &aliases;
|
|
aLocalHost.h_addrtype = AF_INET;
|
|
aLocalHost.h_length = SO_IP4_ALEN;
|
|
|
|
for (i = 0; i < MAX_IPS; i++)
|
|
{
|
|
if (i < aNumOfIps)
|
|
{
|
|
memcpy(&ips[i], &aAddrs[i].addr, sizeof(aAddrs[i].addr));
|
|
ipPtrs[i] = (u8 *)&ips[i];
|
|
}
|
|
else
|
|
ipPtrs[i] = NULL;
|
|
}
|
|
aLocalHost.h_addr_list = ipPtrs;
|
|
|
|
return &aLocalHost;
|
|
|
|
#elif defined(_X360)
|
|
XNADDR addr;
|
|
DWORD rcode;
|
|
static HOSTENT localhost;
|
|
static char * ipPtrs[2];
|
|
static IN_ADDR ip;
|
|
|
|
while((rcode = XNetGetTitleXnAddr(&addr)) == XNET_GET_XNADDR_PENDING)
|
|
msleep(1);
|
|
|
|
if((rcode == XNET_GET_XNADDR_NONE) || (rcode == XNET_GET_XNADDR_TROUBLESHOOT))
|
|
return NULL;
|
|
|
|
localhost.h_name = "localhost";
|
|
localhost.h_aliases = NULL;
|
|
localhost.h_addrtype = AF_INET;
|
|
localhost.h_length = (gsi_u16)sizeof(IN_ADDR);
|
|
localhost.h_addr_list = (gsi_i8 **)ipPtrs;
|
|
|
|
ip = addr.ina;
|
|
ipPtrs[0] = (char *)&ip;
|
|
ipPtrs[1] = NULL;
|
|
|
|
return &localhost;
|
|
|
|
#elif defined(_XBOX)
|
|
return NULL;
|
|
|
|
|
|
#else
|
|
char hostname[256] = "";
|
|
|
|
// get the local host's name
|
|
gethostname(hostname, sizeof(hostname));
|
|
|
|
// return the host for that name
|
|
return gethostbyname(hostname);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
int IsPrivateIP(IN_ADDR * addr)
|
|
{
|
|
int b1;
|
|
int b2;
|
|
unsigned int ip;
|
|
|
|
// get the first 2 bytes
|
|
ip = ntohl(addr->s_addr);
|
|
b1 = (int)((ip >> 24) & 0xFF);
|
|
b2 = (int)((ip >> 16) & 0xFF);
|
|
|
|
// 10.X.X.X
|
|
if(b1 == 10)
|
|
return 1;
|
|
|
|
// 172.16-31.X.X
|
|
if((b1 == 172) && ((b2 >= 16) && (b2 <= 31)))
|
|
return 1;
|
|
|
|
// 192.168.X.X
|
|
if((b1 == 192) && (b2 == 168))
|
|
return 1;
|
|
|
|
return 0;
|
|
}
|
|
|
|
gsi_u32 gsiGetBroadcastIP(void)
|
|
{
|
|
#if defined(_NITRO)
|
|
gsi_u32 ip;
|
|
IP_GetBroadcastAddr(NULL, (u8*)&ip);
|
|
return ip;
|
|
|
|
#elif defined(_REVOLUTION)
|
|
/*
|
|
int length;
|
|
gsi_u32 ip;
|
|
|
|
length = (gsi_u32)sizeof(ip);
|
|
|
|
// IP_GetBroadcastAddr replaced by SOGetInterfaceOpt
|
|
// IP_GetBroadcastAddr(NULL, (u8*)&ip);
|
|
SOGetInterfaceOpt(NULL, SO_SOL_IP, SO_INADDR_BROADCAST, (u8*)&ip, &length);
|
|
*/
|
|
IPAddrEntry* addrtbl;
|
|
int addrnum;
|
|
int ret;
|
|
int length;
|
|
gsi_u32 ip;
|
|
length = (int)sizeof( addrnum );
|
|
|
|
ret = SOGetInterfaceOpt(NULL,
|
|
SO_SOL_CONFIG,
|
|
SO_CONFIG_IP_ADDR_NUMBER,
|
|
(u8*)&addrnum, &length);
|
|
|
|
if( ret >= 0 )
|
|
return 0xFFFFFFFF;
|
|
|
|
|
|
length = (int)(sizeof( IPAddrEntry ) * addrnum);
|
|
|
|
addrtbl = (IPAddrEntry*)gsimalloc( (u32)length );
|
|
|
|
if( addrtbl == NULL )
|
|
return 0xFFFFFFFF;
|
|
|
|
ret = SOGetInterfaceOpt(NULL,
|
|
SO_SOL_CONFIG,
|
|
SO_CONFIG_IP_ADDR_TABLE,
|
|
(u8*)addrtbl,
|
|
&length);
|
|
|
|
if( ret < 0 )
|
|
{
|
|
gsifree( addrtbl );
|
|
return 0xFFFFFFFF;
|
|
}
|
|
|
|
ip = (u32)(addrtbl->bcastAddr[3]
|
|
| (addrtbl->bcastAddr[2] << 8)
|
|
| (addrtbl->bcastAddr[1] << 16)
|
|
| (addrtbl->bcastAddr[0] << 24));
|
|
|
|
gsifree( addrtbl );
|
|
|
|
|
|
return ip;
|
|
|
|
return ip;
|
|
|
|
#else
|
|
return 0xFFFFFFFF;
|
|
#endif
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Re-enable previously disabled compiler warnings
|
|
///////////////////////////////////////////////////
|
|
#if defined(_MSC_VER)
|
|
#pragma warning ( default: 4127 )
|
|
#endif // _MSC_VER
|
|
|