engine: fix potential UB in netadr_t
This commit is contained in:
parent
d4c34abd6e
commit
add02dc6f9
6 changed files with 143 additions and 78 deletions
|
@ -28,7 +28,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
#define PORT_ANY -1
|
#define PORT_ANY -1
|
||||||
|
|
||||||
typedef enum {NA_LOOPBACK = 1, NA_BROADCAST, NA_IP, NA_IPX, NA_BROADCAST_IPX, NA_IP6, NA_MULTICAST_IP6} netadrtype_t;
|
typedef enum netadrtype_e
|
||||||
|
{
|
||||||
|
NA_UNDEFINED = 0,
|
||||||
|
NA_LOOPBACK,
|
||||||
|
NA_BROADCAST,
|
||||||
|
NA_IP,
|
||||||
|
NA_IPX,
|
||||||
|
NA_BROADCAST_IPX,
|
||||||
|
NA_IP6,
|
||||||
|
NA_MULTICAST_IP6
|
||||||
|
} netadrtype_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Original Quake-2 structure:
|
Original Quake-2 structure:
|
||||||
|
@ -46,29 +56,60 @@ typedef struct
|
||||||
#pragma pack( push, 1 )
|
#pragma pack( push, 1 )
|
||||||
typedef struct netadr_s
|
typedef struct netadr_s
|
||||||
{
|
{
|
||||||
|
// the reason we do this evil thing, is that when this struct contains IPv6
|
||||||
|
// address the `type` is 2-byte wide, but when it doesn't `type` must 4-byte
|
||||||
|
// wide _and_ ip6_0 must be zeroed, to keep it binary compatible.
|
||||||
|
#if XASH_LITTLE_ENDIAN
|
||||||
|
uint16_t type;
|
||||||
|
uint8_t ip6_0[2];
|
||||||
|
#elif XASH_BIG_ENDIAN
|
||||||
|
uint8_t ip6_0[2];
|
||||||
|
uint16_t type;
|
||||||
|
#else
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
// IPv6 struct
|
// IPv6 struct
|
||||||
|
uint8_t ip6_1[14];
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint16_t type6;
|
|
||||||
uint8_t ip6[16];
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32_t type; // must be netadrtype_t but will break with short enums
|
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
uint8_t ip[4];
|
uint8_t ip[4];
|
||||||
uint32_t ip4; // for easier conversions
|
uint32_t ip4; // for easier conversions
|
||||||
};
|
};
|
||||||
uint8_t ipx[10];
|
uint8_t ipx[10];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
} netadr_t;
|
} netadr_t;
|
||||||
#pragma pack( pop )
|
#pragma pack( pop )
|
||||||
|
|
||||||
|
static inline netadrtype_t NET_NetadrType( const netadr_t *a )
|
||||||
|
{
|
||||||
|
if( a->type == NA_IP6 || a->type == NA_MULTICAST_IP6 )
|
||||||
|
return a->type;
|
||||||
|
|
||||||
|
if( a->ip6_0[0] || a->ip6_0[1] )
|
||||||
|
return NA_UNDEFINED;
|
||||||
|
|
||||||
|
return a->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void NET_NetadrSetType( netadr_t *a, netadrtype_t type )
|
||||||
|
{
|
||||||
|
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
|
||||||
|
{
|
||||||
|
a->type = type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
a->ip6_0[0] = a->ip6_0[1] = 0;
|
||||||
|
a->type = type;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC_CHECK_SIZEOF( netadr_t, 20, 20 );
|
STATIC_CHECK_SIZEOF( netadr_t, 20, 20 );
|
||||||
|
|
||||||
#endif // NET_ADR_H
|
#endif // NET_ADR_H
|
||||||
|
|
|
@ -3427,7 +3427,7 @@ static void GAME_EXPORT NetAPI_SendRequest( int context, int request, int flags,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( remote_address->type == NA_IPX || remote_address->type == NA_BROADCAST_IPX )
|
if( NET_NetadrType( remote_address ) == NA_IPX || NET_NetadrType( remote_address ) == NA_BROADCAST_IPX )
|
||||||
return; // IPX no longer support
|
return; // IPX no longer support
|
||||||
|
|
||||||
if( request == NETAPI_REQUEST_SERVERLIST )
|
if( request == NETAPI_REQUEST_SERVERLIST )
|
||||||
|
|
|
@ -1063,6 +1063,7 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
|
||||||
const char *key = ID_GetMD5();
|
const char *key = ID_GetMD5();
|
||||||
netadr_t adr = { 0 };
|
netadr_t adr = { 0 };
|
||||||
int input_devices;
|
int input_devices;
|
||||||
|
netadrtype_t adrtype;
|
||||||
|
|
||||||
protinfo[0] = 0;
|
protinfo[0] = 0;
|
||||||
|
|
||||||
|
@ -1073,14 +1074,16 @@ static void CL_SendConnectPacket( connprotocol_t proto, int challenge )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adrtype = NET_NetadrType( &adr );
|
||||||
|
|
||||||
if( adr.port == 0 ) adr.port = MSG_BigShort( PORT_SERVER );
|
if( adr.port == 0 ) adr.port = MSG_BigShort( PORT_SERVER );
|
||||||
|
|
||||||
input_devices = IN_CollectInputDevices();
|
input_devices = IN_CollectInputDevices();
|
||||||
IN_LockInputDevices( adr.type != NA_LOOPBACK ? true : false );
|
IN_LockInputDevices( adrtype != NA_LOOPBACK ? true : false );
|
||||||
|
|
||||||
// GoldSrc doesn't need sv_cheats set to 0, it's handled by svc_goldsrc_sendextrainfo
|
// GoldSrc doesn't need sv_cheats set to 0, it's handled by svc_goldsrc_sendextrainfo
|
||||||
// it also doesn't need useragent string
|
// it also doesn't need useragent string
|
||||||
if( adr.type != NA_LOOPBACK && proto != PROTO_GOLDSRC )
|
if( adrtype != NA_LOOPBACK && proto != PROTO_GOLDSRC )
|
||||||
{
|
{
|
||||||
Cvar_SetCheatState();
|
Cvar_SetCheatState();
|
||||||
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
Cvar_FullSet( "sv_cheats", "0", FCVAR_READ_ONLY | FCVAR_SERVER );
|
||||||
|
@ -1218,7 +1221,7 @@ static void CL_CheckForResend( void )
|
||||||
cls.signon = 0;
|
cls.signon = 0;
|
||||||
cls.state = ca_connecting;
|
cls.state = ca_connecting;
|
||||||
Q_strncpy( cls.servername, "localhost", sizeof( cls.servername ));
|
Q_strncpy( cls.servername, "localhost", sizeof( cls.servername ));
|
||||||
cls.serveradr.type = NA_LOOPBACK;
|
NET_NetadrSetType( &cls.serveradr, NA_LOOPBACK );
|
||||||
cls.legacymode = PROTO_CURRENT;
|
cls.legacymode = PROTO_CURRENT;
|
||||||
|
|
||||||
// we don't need a challenge on the localhost
|
// we don't need a challenge on the localhost
|
||||||
|
@ -1554,8 +1557,8 @@ static void CL_SendDisconnectMessage( connprotocol_t proto )
|
||||||
MSG_WriteString( &buf, "dropclient\n" );
|
MSG_WriteString( &buf, "dropclient\n" );
|
||||||
else MSG_WriteString( &buf, "disconnect" );
|
else MSG_WriteString( &buf, "disconnect" );
|
||||||
|
|
||||||
if( !cls.netchan.remote_address.type )
|
if( NET_NetadrType( &cls.netchan.remote_address ) == NA_UNDEFINED )
|
||||||
cls.netchan.remote_address.type = NA_LOOPBACK;
|
NET_NetadrSetType( &cls.netchan.remote_address, NA_LOOPBACK );
|
||||||
|
|
||||||
// make sure message will be delivered
|
// make sure message will be delivered
|
||||||
Netchan_TransmitBits( &cls.netchan, MSG_GetNumBitsWritten( &buf ), MSG_GetData( &buf ));
|
Netchan_TransmitBits( &cls.netchan, MSG_GetNumBitsWritten( &buf ), MSG_GetData( &buf ));
|
||||||
|
@ -1724,19 +1727,17 @@ CL_LocalServers_f
|
||||||
*/
|
*/
|
||||||
static void CL_LocalServers_f( void )
|
static void CL_LocalServers_f( void )
|
||||||
{
|
{
|
||||||
netadr_t adr;
|
netadr_t adr = { 0 };
|
||||||
|
|
||||||
memset( &adr, 0, sizeof( adr ));
|
|
||||||
|
|
||||||
Con_Printf( "Scanning for servers on the local network area...\n" );
|
Con_Printf( "Scanning for servers on the local network area...\n" );
|
||||||
NET_Config( true, true ); // allow remote
|
NET_Config( true, true ); // allow remote
|
||||||
|
|
||||||
// send a broadcast packet
|
// send a broadcast packet
|
||||||
adr.type = NA_BROADCAST;
|
NET_NetadrSetType( &adr, NA_BROADCAST );
|
||||||
adr.port = MSG_BigShort( PORT_SERVER );
|
adr.port = MSG_BigShort( PORT_SERVER );
|
||||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
|
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
|
||||||
|
|
||||||
adr.type = NA_MULTICAST_IP6;
|
NET_NetadrSetType( &adr, NA_MULTICAST_IP6 );
|
||||||
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
|
Netchan_OutOfBandPrint( NS_CLIENT, adr, A2A_INFO" %i", PROTOCOL_VERSION );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2480,18 +2481,18 @@ static void CL_ServerList( netadr_t from, sizebuf_t *msg )
|
||||||
while( MSG_GetNumBitsLeft( msg ) > 8 )
|
while( MSG_GetNumBitsLeft( msg ) > 8 )
|
||||||
{
|
{
|
||||||
uint8_t addr[16];
|
uint8_t addr[16];
|
||||||
netadr_t servadr;
|
netadr_t servadr = { 0 };
|
||||||
|
|
||||||
if( from.type6 == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
|
if( NET_NetadrType( &from ) == NA_IP6 ) // IPv6 master server only sends IPv6 addresses
|
||||||
{
|
{
|
||||||
MSG_ReadBytes( msg, addr, sizeof( addr ));
|
MSG_ReadBytes( msg, addr, sizeof( addr ));
|
||||||
NET_IP6BytesToNetadr( &servadr, addr );
|
NET_IP6BytesToNetadr( &servadr, addr );
|
||||||
servadr.type6 = NA_IP6;
|
NET_NetadrSetType( &servadr, NA_IP6 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MSG_ReadBytes( msg, servadr.ip, sizeof( servadr.ip )); // 4 bytes for IP
|
MSG_ReadBytes( msg, servadr.ip, sizeof( servadr.ip )); // 4 bytes for IP
|
||||||
servadr.type = NA_IP;
|
NET_NetadrSetType( &servadr, NA_IP );
|
||||||
}
|
}
|
||||||
servadr.port = MSG_ReadShort( msg ); // 2 bytes for Port
|
servadr.port = MSG_ReadShort( msg ); // 2 bytes for Port
|
||||||
|
|
||||||
|
|
|
@ -151,17 +151,24 @@ static inline qboolean NET_IsSocketValid( int socket )
|
||||||
|
|
||||||
void NET_NetadrToIP6Bytes( uint8_t *ip6, const netadr_t *adr )
|
void NET_NetadrToIP6Bytes( uint8_t *ip6, const netadr_t *adr )
|
||||||
{
|
{
|
||||||
memcpy( ip6, adr->ip6, sizeof( adr->ip6 ));
|
memcpy( &ip6[0], adr->ip6_0, 2 );
|
||||||
|
memcpy( &ip6[2], adr->ip6_1, 14 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void NET_IP6BytesToNetadr( netadr_t *adr, const uint8_t *ip6 )
|
void NET_IP6BytesToNetadr( netadr_t *adr, const uint8_t *ip6 )
|
||||||
{
|
{
|
||||||
memcpy( adr->ip6, ip6, sizeof( adr->ip6 ));
|
memcpy( adr->ip6_0, &ip6[0], 2 );
|
||||||
|
memcpy( adr->ip6_1, &ip6[2], 14 );
|
||||||
}
|
}
|
||||||
|
|
||||||
static int NET_NetadrIP6Compare( const netadr_t *a, const netadr_t *b )
|
static int NET_NetadrIP6Compare( const netadr_t *a, const netadr_t *b )
|
||||||
{
|
{
|
||||||
return memcmp( a->ip6, b->ip6, sizeof( a->ip6 ));
|
uint8_t ip6_a[16], ip6_b[16];
|
||||||
|
|
||||||
|
NET_NetadrToIP6Bytes( ip6_a, a );
|
||||||
|
NET_NetadrToIP6Bytes( ip6_b, b );
|
||||||
|
|
||||||
|
return memcmp( ip6_a, ip6_b, sizeof( ip6_a ));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -171,27 +178,29 @@ NET_NetadrToSockadr
|
||||||
*/
|
*/
|
||||||
static void NET_NetadrToSockadr( netadr_t *a, struct sockaddr_storage *s )
|
static void NET_NetadrToSockadr( netadr_t *a, struct sockaddr_storage *s )
|
||||||
{
|
{
|
||||||
|
netadrtype_t type = NET_NetadrType( a );
|
||||||
|
|
||||||
memset( s, 0, sizeof( *s ));
|
memset( s, 0, sizeof( *s ));
|
||||||
|
|
||||||
if( a->type == NA_BROADCAST )
|
if( type == NA_BROADCAST )
|
||||||
{
|
{
|
||||||
s->ss_family = AF_INET;
|
s->ss_family = AF_INET;
|
||||||
((struct sockaddr_in *)s)->sin_port = a->port;
|
((struct sockaddr_in *)s)->sin_port = a->port;
|
||||||
((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
|
((struct sockaddr_in *)s)->sin_addr.s_addr = INADDR_BROADCAST;
|
||||||
}
|
}
|
||||||
else if( a->type == NA_IP )
|
else if( type == NA_IP )
|
||||||
{
|
{
|
||||||
s->ss_family = AF_INET;
|
s->ss_family = AF_INET;
|
||||||
((struct sockaddr_in *)s)->sin_port = a->port;
|
((struct sockaddr_in *)s)->sin_port = a->port;
|
||||||
((struct sockaddr_in *)s)->sin_addr.s_addr = a->ip4;
|
((struct sockaddr_in *)s)->sin_addr.s_addr = a->ip4;
|
||||||
}
|
}
|
||||||
else if( a->type6 == NA_IP6 )
|
else if( type == NA_IP6 )
|
||||||
{
|
{
|
||||||
s->ss_family = AF_INET6;
|
s->ss_family = AF_INET6;
|
||||||
((struct sockaddr_in6 *)s)->sin6_port = a->port;
|
((struct sockaddr_in6 *)s)->sin6_port = a->port;
|
||||||
NET_NetadrToIP6Bytes(((struct sockaddr_in6 *)s)->sin6_addr.s6_addr, a );
|
NET_NetadrToIP6Bytes(((struct sockaddr_in6 *)s)->sin6_addr.s6_addr, a );
|
||||||
}
|
}
|
||||||
else if( a->type6 == NA_MULTICAST_IP6 )
|
else if( type == NA_MULTICAST_IP6 )
|
||||||
{
|
{
|
||||||
s->ss_family = AF_INET6;
|
s->ss_family = AF_INET6;
|
||||||
((struct sockaddr_in6 *)s)->sin6_port = a->port;
|
((struct sockaddr_in6 *)s)->sin6_port = a->port;
|
||||||
|
@ -208,13 +217,13 @@ static void NET_SockadrToNetadr( const struct sockaddr_storage *s, netadr_t *a )
|
||||||
{
|
{
|
||||||
if( s->ss_family == AF_INET )
|
if( s->ss_family == AF_INET )
|
||||||
{
|
{
|
||||||
a->type = NA_IP;
|
NET_NetadrSetType( a, NA_IP );
|
||||||
a->ip4 = ((struct sockaddr_in *)s)->sin_addr.s_addr;
|
a->ip4 = ((struct sockaddr_in *)s)->sin_addr.s_addr;
|
||||||
a->port = ((struct sockaddr_in *)s)->sin_port;
|
a->port = ((struct sockaddr_in *)s)->sin_port;
|
||||||
}
|
}
|
||||||
else if( s->ss_family == AF_INET6 )
|
else if( s->ss_family == AF_INET6 )
|
||||||
{
|
{
|
||||||
a->type6 = NA_IP6;
|
NET_NetadrSetType( a, NA_IP6 );
|
||||||
NET_IP6BytesToNetadr( a, ((struct sockaddr_in6 *)s)->sin6_addr.s6_addr );
|
NET_IP6BytesToNetadr( a, ((struct sockaddr_in6 *)s)->sin6_addr.s6_addr );
|
||||||
a->port = ((struct sockaddr_in6 *)s)->sin6_port;
|
a->port = ((struct sockaddr_in6 *)s)->sin6_port;
|
||||||
}
|
}
|
||||||
|
@ -549,8 +558,8 @@ qboolean NET_StringToFilterAdr( const char *s, netadr_t *adr, uint *prefixlen )
|
||||||
// try to parse as IPv6 first
|
// try to parse as IPv6 first
|
||||||
if( ParseIPv6Addr( copy, ip6, NULL, NULL ))
|
if( ParseIPv6Addr( copy, ip6, NULL, NULL ))
|
||||||
{
|
{
|
||||||
|
NET_NetadrSetType( adr, NA_IP6 );
|
||||||
NET_IP6BytesToNetadr( adr, ip6 );
|
NET_IP6BytesToNetadr( adr, ip6 );
|
||||||
adr->type6 = NA_IP6;
|
|
||||||
|
|
||||||
if( !hasCIDR )
|
if( !hasCIDR )
|
||||||
*prefixlen = 128;
|
*prefixlen = 128;
|
||||||
|
@ -620,7 +629,7 @@ qboolean NET_StringToFilterAdr( const char *s, netadr_t *adr, uint *prefixlen )
|
||||||
adr->ip4 = ntohl( mask );
|
adr->ip4 = ntohl( mask );
|
||||||
}
|
}
|
||||||
|
|
||||||
adr->type = NA_IP;
|
NET_NetadrSetType( adr, NA_IP );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -634,10 +643,11 @@ NET_AdrToString
|
||||||
const char *NET_AdrToString( const netadr_t a )
|
const char *NET_AdrToString( const netadr_t a )
|
||||||
{
|
{
|
||||||
static char s[64];
|
static char s[64];
|
||||||
|
netadrtype_t type = NET_NetadrType( &a );
|
||||||
|
|
||||||
if( a.type == NA_LOOPBACK )
|
if( type == NA_LOOPBACK )
|
||||||
return "loopback";
|
return "loopback";
|
||||||
if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
|
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
|
||||||
{
|
{
|
||||||
uint8_t ip6[16];
|
uint8_t ip6[16];
|
||||||
|
|
||||||
|
@ -661,10 +671,11 @@ NET_BaseAdrToString
|
||||||
const char *NET_BaseAdrToString( const netadr_t a )
|
const char *NET_BaseAdrToString( const netadr_t a )
|
||||||
{
|
{
|
||||||
static char s[64];
|
static char s[64];
|
||||||
|
netadrtype_t type = NET_NetadrType( &a );
|
||||||
|
|
||||||
if( a.type == NA_LOOPBACK )
|
if( type == NA_LOOPBACK )
|
||||||
return "loopback";
|
return "loopback";
|
||||||
if( a.type6 == NA_IP6 || a.type6 == NA_MULTICAST_IP6 )
|
if( type == NA_IP6 || type == NA_MULTICAST_IP6 )
|
||||||
{
|
{
|
||||||
uint8_t ip6[16];
|
uint8_t ip6[16];
|
||||||
|
|
||||||
|
@ -689,16 +700,19 @@ Compares without the port
|
||||||
*/
|
*/
|
||||||
qboolean NET_CompareBaseAdr( const netadr_t a, const netadr_t b )
|
qboolean NET_CompareBaseAdr( const netadr_t a, const netadr_t b )
|
||||||
{
|
{
|
||||||
if( a.type6 != b.type6 )
|
netadrtype_t type_a = NET_NetadrType( &a );
|
||||||
|
netadrtype_t type_b = NET_NetadrType( &b );
|
||||||
|
|
||||||
|
if( type_a != type_b )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( a.type == NA_LOOPBACK )
|
if( type_a == NA_LOOPBACK )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( a.type == NA_IP )
|
if( type_a == NA_IP )
|
||||||
return a.ip4 == b.ip4;
|
return a.ip4 == b.ip4;
|
||||||
|
|
||||||
if( a.type6 == NA_IP6 )
|
if( type_a == NA_IP6 )
|
||||||
{
|
{
|
||||||
if( !NET_NetadrIP6Compare( &a, &b ))
|
if( !NET_NetadrIP6Compare( &a, &b ))
|
||||||
return true;
|
return true;
|
||||||
|
@ -716,13 +730,16 @@ Compare local masks
|
||||||
*/
|
*/
|
||||||
qboolean NET_CompareClassBAdr( const netadr_t a, const netadr_t b )
|
qboolean NET_CompareClassBAdr( const netadr_t a, const netadr_t b )
|
||||||
{
|
{
|
||||||
if( a.type6 != b.type6 )
|
netadrtype_t type_a = NET_NetadrType( &a );
|
||||||
|
netadrtype_t type_b = NET_NetadrType( &b );
|
||||||
|
|
||||||
|
if( type_a != type_b )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( a.type == NA_LOOPBACK )
|
if( type_a == NA_LOOPBACK )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( a.type == NA_IP )
|
if( type_a == NA_IP )
|
||||||
{
|
{
|
||||||
if( a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] )
|
if( a.ip[0] == b.ip[0] && a.ip[1] == b.ip[1] )
|
||||||
return true;
|
return true;
|
||||||
|
@ -746,10 +763,13 @@ Checks if adr is a part of subnet
|
||||||
*/
|
*/
|
||||||
qboolean NET_CompareAdrByMask( const netadr_t a, const netadr_t b, uint prefixlen )
|
qboolean NET_CompareAdrByMask( const netadr_t a, const netadr_t b, uint prefixlen )
|
||||||
{
|
{
|
||||||
if( a.type6 != b.type6 || a.type == NA_LOOPBACK )
|
netadrtype_t type_a = NET_NetadrType( &a );
|
||||||
|
netadrtype_t type_b = NET_NetadrType( &b );
|
||||||
|
|
||||||
|
if( type_a != type_b || type_a == NA_LOOPBACK )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( a.type == NA_IP )
|
if( type_a == NA_IP )
|
||||||
{
|
{
|
||||||
uint32_t ipa = htonl( a.ip4 );
|
uint32_t ipa = htonl( a.ip4 );
|
||||||
uint32_t ipb = htonl( b.ip4 );
|
uint32_t ipb = htonl( b.ip4 );
|
||||||
|
@ -757,7 +777,7 @@ qboolean NET_CompareAdrByMask( const netadr_t a, const netadr_t b, uint prefixle
|
||||||
if(( ipa & (( 0xFFFFFFFFU ) << ( 32 - prefixlen ))) == ipb )
|
if(( ipa & (( 0xFFFFFFFFU ) << ( 32 - prefixlen ))) == ipb )
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if( a.type6 == NA_IP6 )
|
else if( type_a == NA_IP6 )
|
||||||
{
|
{
|
||||||
uint16_t a_[8], b_[8];
|
uint16_t a_[8], b_[8];
|
||||||
size_t check = prefixlen / 16;
|
size_t check = prefixlen / 16;
|
||||||
|
@ -798,11 +818,13 @@ Check for reserved ip's
|
||||||
*/
|
*/
|
||||||
qboolean NET_IsReservedAdr( netadr_t a )
|
qboolean NET_IsReservedAdr( netadr_t a )
|
||||||
{
|
{
|
||||||
if( a.type == NA_LOOPBACK )
|
netadrtype_t type_a = NET_NetadrType( &a );
|
||||||
|
|
||||||
|
if( type_a == NA_LOOPBACK )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Following checks was imported from GameNetworkingSockets library
|
// Following checks was imported from GameNetworkingSockets library
|
||||||
if( a.type == NA_IP )
|
if( type_a == NA_IP )
|
||||||
{
|
{
|
||||||
if(( a.ip[0] == 10 ) || // 10.x.x.x is reserved
|
if(( a.ip[0] == 10 ) || // 10.x.x.x is reserved
|
||||||
( a.ip[0] == 127 ) || // 127.x.x.x
|
( a.ip[0] == 127 ) || // 127.x.x.x
|
||||||
|
@ -814,7 +836,7 @@ qboolean NET_IsReservedAdr( netadr_t a )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( a.type6 == NA_IP6 )
|
if( type_a == NA_IP6 )
|
||||||
{
|
{
|
||||||
uint8_t ip6[16];
|
uint8_t ip6[16];
|
||||||
|
|
||||||
|
@ -847,20 +869,23 @@ Compare full address
|
||||||
*/
|
*/
|
||||||
qboolean NET_CompareAdr( const netadr_t a, const netadr_t b )
|
qboolean NET_CompareAdr( const netadr_t a, const netadr_t b )
|
||||||
{
|
{
|
||||||
if( a.type6 != b.type6 )
|
netadrtype_t type_a = NET_NetadrType( &a );
|
||||||
|
netadrtype_t type_b = NET_NetadrType( &b );
|
||||||
|
|
||||||
|
if( type_a != type_b )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( a.type == NA_LOOPBACK )
|
if( type_a == NA_LOOPBACK )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( a.type == NA_IP )
|
if( type_a == NA_IP )
|
||||||
{
|
{
|
||||||
if( a.ip4 == b.ip4 && a.port == b.port )
|
if( a.ip4 == b.ip4 && a.port == b.port )
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( a.type6 == NA_IP6 )
|
if( type_a == NA_IP6 )
|
||||||
{
|
{
|
||||||
if( a.port == b.port && !NET_NetadrIP6Compare( &a, &b ))
|
if( a.port == b.port && !NET_NetadrIP6Compare( &a, &b ))
|
||||||
return true;
|
return true;
|
||||||
|
@ -883,9 +908,13 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
|
||||||
{
|
{
|
||||||
const netadr_t *a = _a, *b = _b;
|
const netadr_t *a = _a, *b = _b;
|
||||||
int porta, portb, portdiff, addrdiff;
|
int porta, portb, portdiff, addrdiff;
|
||||||
|
netadrtype_t type_a, type_b;
|
||||||
|
|
||||||
if( a->type6 != b->type6 )
|
type_a = NET_NetadrType( a );
|
||||||
return bound( -1, (int)a->type6 - (int)b->type6, 1 );
|
type_b = NET_NetadrType( b );
|
||||||
|
|
||||||
|
if( type_a != type_b )
|
||||||
|
return bound( -1, (int)type_a - (int)type_b, 1 );
|
||||||
|
|
||||||
porta = ntohs( a->port );
|
porta = ntohs( a->port );
|
||||||
portb = ntohs( b->port );
|
portb = ntohs( b->port );
|
||||||
|
@ -896,7 +925,7 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
|
||||||
else
|
else
|
||||||
portdiff = 0;
|
portdiff = 0;
|
||||||
|
|
||||||
switch( a->type6 )
|
switch( type_a )
|
||||||
{
|
{
|
||||||
case NA_IP6:
|
case NA_IP6:
|
||||||
if(( addrdiff = NET_NetadrIP6Compare( a, b )))
|
if(( addrdiff = NET_NetadrIP6Compare( a, b )))
|
||||||
|
@ -904,14 +933,7 @@ int NET_CompareAdrSort( const void *_a, const void *_b )
|
||||||
// fallthrough
|
// fallthrough
|
||||||
case NA_MULTICAST_IP6:
|
case NA_MULTICAST_IP6:
|
||||||
return portdiff;
|
return portdiff;
|
||||||
}
|
|
||||||
|
|
||||||
// don't check for full type earlier, as it's value depends on v6 address
|
|
||||||
if( a->type != b->type )
|
|
||||||
return bound( -1, (int)a->type - (int)b->type, 1 );
|
|
||||||
|
|
||||||
switch( a->type )
|
|
||||||
{
|
|
||||||
case NA_IP:
|
case NA_IP:
|
||||||
if(( addrdiff = memcmp( a->ip, b->ip, sizeof( a->ipx ))))
|
if(( addrdiff = memcmp( a->ip, b->ip, sizeof( a->ipx ))))
|
||||||
return addrdiff;
|
return addrdiff;
|
||||||
|
@ -946,7 +968,7 @@ static qboolean NET_StringToAdrEx( const char *string, netadr_t *adr, int family
|
||||||
|
|
||||||
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
|
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
|
||||||
{
|
{
|
||||||
adr->type = NA_LOOPBACK;
|
NET_NetadrSetType( adr, NA_LOOPBACK );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -971,7 +993,7 @@ net_gai_state_t NET_StringToAdrNB( const char *string, netadr_t *adr, qboolean v
|
||||||
|
|
||||||
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
|
if( !Q_stricmp( string, "localhost" ) || !Q_stricmp( string, "loopback" ))
|
||||||
{
|
{
|
||||||
adr->type = NA_LOOPBACK;
|
NET_NetadrSetType( adr, NA_LOOPBACK );
|
||||||
return NET_EAI_OK;
|
return NET_EAI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1017,7 +1039,7 @@ static qboolean NET_GetLoopPacket( netsrc_t sock, netadr_t *from, byte *data, si
|
||||||
*length = loop->msgs[i].datalen;
|
*length = loop->msgs[i].datalen;
|
||||||
|
|
||||||
memset( from, 0, sizeof( *from ));
|
memset( from, 0, sizeof( *from ));
|
||||||
from->type = NA_LOOPBACK;
|
NET_NetadrSetType( from, NA_LOOPBACK );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1546,19 +1568,20 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
|
||||||
int ret;
|
int ret;
|
||||||
struct sockaddr_storage addr = { 0 };
|
struct sockaddr_storage addr = { 0 };
|
||||||
SOCKET net_socket = 0;
|
SOCKET net_socket = 0;
|
||||||
|
netadrtype_t type = NET_NetadrType( &to );
|
||||||
|
|
||||||
if( !net.initialized || to.type == NA_LOOPBACK )
|
if( !net.initialized || type == NA_LOOPBACK )
|
||||||
{
|
{
|
||||||
NET_SendLoopPacket( sock, length, data, to );
|
NET_SendLoopPacket( sock, length, data, to );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if( to.type == NA_BROADCAST || to.type == NA_IP )
|
else if( type == NA_BROADCAST || type == NA_IP )
|
||||||
{
|
{
|
||||||
net_socket = net.ip_sockets[sock];
|
net_socket = net.ip_sockets[sock];
|
||||||
if( !NET_IsSocketValid( net_socket ))
|
if( !NET_IsSocketValid( net_socket ))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if( to.type6 == NA_MULTICAST_IP6 || to.type6 == NA_IP6 )
|
else if( type == NA_MULTICAST_IP6 || type == NA_IP6 )
|
||||||
{
|
{
|
||||||
net_socket = net.ip6_sockets[sock];
|
net_socket = net.ip6_sockets[sock];
|
||||||
if( !NET_IsSocketValid( net_socket ))
|
if( !NET_IsSocketValid( net_socket ))
|
||||||
|
@ -1566,7 +1589,7 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Host_Error( "%s: bad address type %i (%i)\n", __func__, to.type, to.type6 );
|
Host_Error( "%s: bad address type %i (%i, %i)\n", __func__, to.type, to.ip6_0[0], to.ip6_0[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
NET_NetadrToSockadr( &to, &addr );
|
NET_NetadrToSockadr( &to, &addr );
|
||||||
|
@ -1582,7 +1605,7 @@ void NET_SendPacketEx( netsrc_t sock, size_t length, const void *data, netadr_t
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// some PPP links don't allow broadcasts
|
// some PPP links don't allow broadcasts
|
||||||
if( err == WSAEADDRNOTAVAIL && ( to.type == NA_BROADCAST || to.type6 == NA_MULTICAST_IP6 ))
|
if( err == WSAEADDRNOTAVAIL && ( type == NA_BROADCAST || type == NA_MULTICAST_IP6 ))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( Host_IsDedicated( ))
|
if( Host_IsDedicated( ))
|
||||||
|
|
|
@ -80,7 +80,7 @@ void NET_NetadrToIP6Bytes( uint8_t *ip6, const netadr_t *adr );
|
||||||
|
|
||||||
static inline qboolean NET_IsLocalAddress( netadr_t adr )
|
static inline qboolean NET_IsLocalAddress( netadr_t adr )
|
||||||
{
|
{
|
||||||
return adr.type == NA_LOOPBACK ? true : false;
|
return NET_NetadrType( &adr ) == NA_LOOPBACK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !XASH_DEDICATED
|
#if !XASH_DEDICATED
|
||||||
|
|
|
@ -302,7 +302,7 @@ static int SV_FilterToString( char *dest, size_t size, qboolean config, ipfilter
|
||||||
|
|
||||||
static qboolean SV_IPFilterIncludesIPFilter( ipfilter_t *a, ipfilter_t *b )
|
static qboolean SV_IPFilterIncludesIPFilter( ipfilter_t *a, ipfilter_t *b )
|
||||||
{
|
{
|
||||||
if( a->adr.type6 != b->adr.type6 )
|
if( NET_NetadrType( &a->adr ) != NET_NetadrType( &b->adr ))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// can't include bigger subnet in small
|
// can't include bigger subnet in small
|
||||||
|
@ -359,7 +359,7 @@ qboolean SV_CheckIP( netadr_t *adr )
|
||||||
if( entry->endTime && host.realtime > entry->endTime )
|
if( entry->endTime && host.realtime > entry->endTime )
|
||||||
continue; // expired
|
continue; // expired
|
||||||
|
|
||||||
switch( entry->adr.type6 )
|
switch( NET_NetadrType( &entry->adr ))
|
||||||
{
|
{
|
||||||
case NA_IP:
|
case NA_IP:
|
||||||
case NA_IP6:
|
case NA_IP6:
|
||||||
|
|
Loading…
Add table
Reference in a new issue