Exemplo n.º 1
0
/*
====================
NET_SetMulticast
Set the current multicast group
====================
*/
void NET_SetMulticast6( void )
{
    struct sockaddr_in6 addr;

    if ( !*net_mcast6addr->string || !Sys_StringToSockaddr( net_mcast6addr->string, ( struct sockaddr * ) &addr, sizeof( addr ), AF_INET6 ) )
    {
        Com_Printf(_( "WARNING: NET_JoinMulticast6: Incorrect multicast address given, "
                      "please set cvar %s to a sane value.\n"), net_mcast6addr->name );

        Cvar_SetValue( net_enabled->name, net_enabled->integer | NET_DISABLEMCAST );

        return;
    }

    memcpy( &curgroup.ipv6mr_multiaddr, &addr.sin6_addr, sizeof( curgroup.ipv6mr_multiaddr ) );

    if ( *net_mcast6iface->string )
    {
#ifdef _WIN32
        curgroup.ipv6mr_interface = net_mcast6iface->integer;
#else
        curgroup.ipv6mr_interface = if_nametoindex( net_mcast6iface->string );
#endif
    }
    else
    {
        curgroup.ipv6mr_interface = 0;
    }
}
Exemplo n.º 2
0
/*
=============
Sys_StringToAdr
=============
*/
qboolean Sys_StringToAdr( const char *s, netadr_t *a, netadrtype_t family )
{
    struct sockaddr_storage sadr;

    sa_family_t             fam;

    switch ( family )
    {
    case NA_IP:
        fam = AF_INET;
        break;

    case NA_IP6:
        fam = AF_INET6;
        break;

    default:
        fam = AF_UNSPEC;
        break;
    }

    if ( !Sys_StringToSockaddr( s, ( struct sockaddr * ) &sadr, sizeof( sadr ), fam ) )
    {
        return qfalse;
    }

    SockadrToNetadr( ( struct sockaddr * ) &sadr, a );
    return qtrue;
}
Exemplo n.º 3
0
/*
====================
NET_IPSocket
====================
*/
int NET_IPSocket( char *net_interface, int port ) {
	SOCKET newsocket;
	struct sockaddr_in address;
//bani - was improper parameter
	unsigned long _true = qtrue;
	int i = 1;
	int err;

	if ( net_interface ) {
		Com_Printf( "Opening IP socket: %s:%i\n", net_interface, port );
	} else {
		Com_Printf( "Opening IP socket: localhost:%i\n", port );
	}

	if ( ( newsocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET ) {
		err = WSAGetLastError();
		if ( err != WSAEAFNOSUPPORT ) {
			Com_Printf( "WARNING: UDP_OpenSocket: socket: %s\n", NET_ErrorString() );
		}
		return 0;
	}

	// make it non-blocking
	if ( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR ) {
		Com_Printf( "WARNING: UDP_OpenSocket: ioctl FIONBIO: %s\n", NET_ErrorString() );
		return 0;
	}

	// make it broadcast capable
	if ( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof( i ) ) == SOCKET_ERROR ) {
		Com_Printf( "WARNING: UDP_OpenSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() );
		return 0;
	}

	if ( !net_interface || !net_interface[0] || !Q_stricmp( net_interface, "localhost" ) ) {
		address.sin_addr.s_addr = INADDR_ANY;
	} else {
		Sys_StringToSockaddr( net_interface, (struct sockaddr *)&address );
	}

	if ( port == PORT_ANY ) {
		address.sin_port = 0;
	} else {
		address.sin_port = htons( (short)port );
	}

	address.sin_family = AF_INET;

	if ( bind( newsocket, (void *)&address, sizeof( address ) ) == SOCKET_ERROR ) {
		Com_Printf( "WARNING: UDP_OpenSocket: bind: %s\n", NET_ErrorString() );
		closesocket( newsocket );
		return 0;
	}

	//bani
	NET_GetInterfaces();

	return newsocket;
}
Exemplo n.º 4
0
/*
====================
NET_IPSocket
====================
 */
int NET_IPSocket(char *net_interface, int port, int *err) {
    SOCKET newsocket;
    struct sockaddr_in address;
    u_long _true = 1;
    int i = 1;

    *err = 0;

    if (net_interface) {
        Com_Printf("Opening IP socket: %s:%i\n", net_interface, port);
    } else {
        Com_Printf("Opening IP socket: 0.0.0.0:%i\n", port);
    }

    if ((newsocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
        *err = socketError;
        Com_Printf("WARNING: NET_IPSocket: socket: %s\n", NET_ErrorString());
        return newsocket;
    }
    // make it non-blocking
    if (ioctlsocket(newsocket, FIONBIO, &_true) == SOCKET_ERROR) {
        Com_Printf("WARNING: NET_IPSocket: ioctl FIONBIO: %s\n", NET_ErrorString());
        *err = socketError;
        closesocket(newsocket);
        return INVALID_SOCKET;
    }

    // make it broadcast capable
    if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *) & i, sizeof (i)) == SOCKET_ERROR) {
        Com_Printf("WARNING: NET_IPSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString());
    }

    if (!net_interface || !net_interface[0]) {
        address.sin_family = AF_INET;
        address.sin_addr.s_addr = INADDR_ANY;
    } else {
        if (!Sys_StringToSockaddr(net_interface, (struct sockaddr *) & address, sizeof (address), AF_INET)) {
            closesocket(newsocket);
            return INVALID_SOCKET;
        }
    }

    if (port == PORT_ANY) {
        address.sin_port = 0;
    } else {
        address.sin_port = htons((short) port);
    }

    if (bind(newsocket, (void *) & address, sizeof (address)) == SOCKET_ERROR) {
        Com_Printf("WARNING: NET_IPSocket: bind: %s\n", NET_ErrorString());
        *err = socketError;
        closesocket(newsocket);
        return INVALID_SOCKET;
    }

    return newsocket;
}
Exemplo n.º 5
0
/*
=============
Sys_StringToAdr

idnewt
192.246.40.70
=============
*/
qboolean Sys_StringToAdr( const char *s, netadr_t *a ) {
	struct sockaddr sadr;
	
	if ( !Sys_StringToSockaddr( s, &sadr ) ) {
		return qfalse;
	}
	
	SockadrToNetadr( &sadr, a );
	return qtrue;
}
Exemplo n.º 6
0
/*
====================
Sys_ResolveListenAddresses

Step 2 - Resolve the address names of all the listening sockets
====================
*/
qboolean Sys_ResolveListenAddresses (void)
{
	// If nothing to resolve, add the local IPv4 & IPv6 addresses
	if (nb_sockets == 0)
	{
		const sa_family_t addr_families [] = { AF_INET, AF_INET6 };
		const unsigned int nb_addrs = sizeof (addr_families) / sizeof (addr_families[0]);
		unsigned int addr_ind;

		memset (listen_sockets, 0, sizeof (listen_sockets[0]) * nb_addrs);

		for (addr_ind = 0; addr_ind < nb_addrs; addr_ind++)
		{
			if (! Sys_BuildSockaddr (NULL, NULL, addr_families[addr_ind],
									 &listen_sockets[addr_ind].local_addr,
									 &listen_sockets[addr_ind].local_addr_len))
				return false;

			listen_sockets[addr_ind].optional = true;
			nb_sockets++;
		}
	}
	else
	{
		unsigned int sock_ind;

		for (sock_ind = 0; sock_ind < nb_sockets; sock_ind++)
		{
			listen_socket_t* listen_sock = &listen_sockets[sock_ind];

			if (! Sys_StringToSockaddr (listen_sock->local_addr_name,
										&listen_sock->local_addr,
										&listen_sock->local_addr_len))
				return false;
		}
	}

	return true;
}
Exemplo n.º 7
0
/*
====================
NET_IP6Socket
====================
*/
int NET_IP6Socket( char *net_interface, int port, struct sockaddr_in6 *bindto, int *err )
{
    SOCKET              newsocket;
    struct sockaddr_in6 address;

    u_long              _true = 1;

    *err = 0;

    if ( net_interface )
    {
        // Print the name in brackets if there is a colon:
        if ( Q_CountChar( net_interface, ':' ) )
        {
            Com_Printf(_( "Opening IP6 socket: [%s]:%i\n"), net_interface, port );
        }
        else
        {
            Com_Printf(_( "Opening IP6 socket: %s:%i\n"), net_interface, port );
        }
    }
    else
    {
        Com_Printf(_( "Opening IP6 socket: [::]:%i\n"), port );
    }

    if ( ( newsocket = socket( PF_INET6, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET )
    {
        *err = socketError;
        Com_Printf(_( "WARNING: NET_IP6Socket: socket: %s\n"), NET_ErrorString() );
        return newsocket;
    }

    // make it non-blocking
    if ( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR )
    {
        Com_Printf(_( "WARNING: NET_IP6Socket: ioctl FIONBIO: %s\n"), NET_ErrorString() );
        *err = socketError;
        closesocket( newsocket );
        return INVALID_SOCKET;
    }

#ifdef IPV6_V6ONLY
    {
        int i = 1;

        // ipv4 addresses should not be allowed to connect via this socket.
        if ( setsockopt( newsocket, IPPROTO_IPV6, IPV6_V6ONLY, ( char * ) &i, sizeof( i ) ) == SOCKET_ERROR )
        {
            // win32 systems don't seem to support this anyways.
            Com_DPrintf( "WARNING: NET_IP6Socket: setsockopt IPV6_V6ONLY: %s\n", NET_ErrorString() );
        }
    }
#endif

    if ( !net_interface || !net_interface[ 0 ] )
    {
        address.sin6_family = AF_INET6;
        address.sin6_addr = in6addr_any;
    }
    else
    {
        if ( !Sys_StringToSockaddr( net_interface, ( struct sockaddr * ) &address, sizeof( address ), AF_INET6 ) )
        {
            closesocket( newsocket );
            return INVALID_SOCKET;
        }
    }

    if ( port == PORT_ANY )
    {
        address.sin6_port = 0;
    }
    else
    {
        address.sin6_port = htons( ( short ) port );
    }

    if ( bind( newsocket, ( void * ) &address, sizeof( address ) ) == SOCKET_ERROR )
    {
        Com_Printf(_( "WARNING: NET_IP6Socket: bind: %s\n"), NET_ErrorString() );
        *err = socketError;
        closesocket( newsocket );
        return INVALID_SOCKET;
    }

    if ( bindto )
    {
        *bindto = address;
    }

    return newsocket;
}
Exemplo n.º 8
0
/*
====================
NET_IP6Socket
====================
*/
SOCKET NET_IP6Socket( const char *net_interface, int port, struct sockaddr_in6 *bindto, int *err )
{
	SOCKET              newsocket;
	struct sockaddr_in6 address;

	u_long              _true = 1;
	qboolean            brackets = net_interface && Q_CountChar( net_interface, ':' );

	*err = 0;

	// Print the name in brackets if there is a colon:
	Com_Printf(_( "Opening IP6 socket: %s%s%s:%s\n"), brackets ? "[" : "", net_interface ? net_interface : "[::]", brackets ? "]" : "", port ? va( "%i", port ) : "*" );

	if ( ( newsocket = socket( PF_INET6, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET )
	{
		*err = socketError;
		Com_Printf( "WARNING: NET_IP6Socket: socket: %s\n", NET_ErrorString() );
		return newsocket;
	}

	// make it non-blocking
	if ( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR )
	{
		Com_Printf( "WARNING: NET_IP6Socket: ioctl FIONBIO: %s\n", NET_ErrorString() );
		*err = socketError;
		closesocket( newsocket );
		return INVALID_SOCKET;
	}

#ifdef IPV6_V6ONLY
	{
		int i = 1;

		// IPv4 addresses should not be allowed to connect via this socket.
		if ( setsockopt( newsocket, IPPROTO_IPV6, IPV6_V6ONLY, ( char * ) &i, sizeof( i ) ) == SOCKET_ERROR )
		{
			// win32 systems don't seem to support this anyways.
			Com_DPrintf( "WARNING: NET_IP6Socket: setsockopt IPV6_V6ONLY: %s\n", NET_ErrorString() );
		}
	}
#endif

	if ( !net_interface || !net_interface[ 0 ] )
	{
		address.sin6_family = AF_INET6;
		address.sin6_addr = in6addr_any;
	}
	else
	{
		if ( !Sys_StringToSockaddr( net_interface, ( struct sockaddr * ) &address, sizeof( address ), AF_INET6 ) )
		{
			closesocket( newsocket );
			return INVALID_SOCKET;
		}
	}

	address.sin6_port = htons( ( short ) port );

	if ( bind( newsocket, ( void * ) &address, sizeof( address ) ) == SOCKET_ERROR )
	{
		Com_Printf( "WARNING: NET_IP6Socket: bind: %s\n", NET_ErrorString() );
		*err = socketError;
		closesocket( newsocket );
		return INVALID_SOCKET;
	}

	if ( bindto )
	{
		// random port? find what was chosen
		if ( address.sin6_port == 0 )
		{
			struct sockaddr_in6 addr; // enough space
			socklen_t           addrlen = sizeof( addr );

			if ( !getsockname( newsocket, (struct sockaddr *) &addr, &addrlen ) && addrlen )
			{
				address.sin6_port = addr.sin6_port;
			}
		}
		*bindto = address;
	}

	return newsocket;
}
Exemplo n.º 9
0
/*
====================
NET_IPSocket
====================
*/
SOCKET NET_IPSocket( const char *net_interface, int port, struct sockaddr_in *bindto, int *err )
{
	SOCKET             newsocket;
	struct sockaddr_in address;

	u_long             _true = 1;
	int                i = 1;

	*err = 0;

	Com_Printf(_( "Opening IP socket: %s:%s\n"), net_interface ? net_interface : "0.0.0.0", port ? va( "%i", port ) : "*" );

	if ( ( newsocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) == INVALID_SOCKET )
	{
		*err = socketError;
		Com_Printf( "WARNING: NET_IPSocket: socket: %s\n", NET_ErrorString() );
		return newsocket;
	}

	// make it non-blocking
	if ( ioctlsocket( newsocket, FIONBIO, &_true ) == SOCKET_ERROR )
	{
		Com_Printf( "WARNING: NET_IPSocket: ioctl FIONBIO: %s\n", NET_ErrorString() );
		*err = socketError;
		closesocket( newsocket );
		return INVALID_SOCKET;
	}

	// make it broadcast capable
	if ( setsockopt( newsocket, SOL_SOCKET, SO_BROADCAST, ( char * ) &i, sizeof( i ) ) == SOCKET_ERROR )
	{
		Com_Printf( "WARNING: NET_IPSocket: setsockopt SO_BROADCAST: %s\n", NET_ErrorString() );
	}

	if ( !net_interface || !net_interface[ 0 ] )
	{
		address.sin_family = AF_INET;
		address.sin_addr.s_addr = INADDR_ANY;
	}
	else
	{
		if ( !Sys_StringToSockaddr( net_interface, ( struct sockaddr * ) &address, sizeof( address ), AF_INET ) )
		{
			closesocket( newsocket );
			return INVALID_SOCKET;
		}
	}

	address.sin_port = htons( ( short ) port );

	if ( bind( newsocket, ( void * ) &address, sizeof( address ) ) == SOCKET_ERROR )
	{
		Com_Printf( "WARNING: NET_IPSocket: bind: %s\n", NET_ErrorString() );
		*err = socketError;
		closesocket( newsocket );
		return INVALID_SOCKET;
	}

	if ( bindto )
	{
		// random port? find what was chosen
		if ( address.sin_port == 0 )
		{
			struct sockaddr_in addr; // enough space
			socklen_t          addrlen = sizeof( addr );

			if ( !getsockname( newsocket, (struct sockaddr *) &addr, &addrlen ) && addrlen )
			{
				address.sin_port = addr.sin_port;
			}
		}

		*bindto = address;
	}

	return newsocket;
}
Exemplo n.º 10
0
qboolean Sys_StringToSockaddr( const char *s, struct sockaddr *sadr ) {
	struct hostent  *h;
	int val;
	char copy[MAX_STRING_CHARS];

	memset( sadr, 0, sizeof( *sadr ) );

	// check for an IPX address

#if !defined RTCW_ET
	if ( ( strlen( s ) == 21 ) && ( s[8] == '.' ) ) {
#else
	// rain - too easy to falsely match a real hostname
//	if( ( strlen( s ) == 21 ) && ( s[8] == '.' ) ) {
	if ( NET_IsIPXAddress( s ) ) {
#endif // RTCW_XX

		( (struct sockaddr_ipx *)sadr )->sa_family = AF_IPX;
		( (struct sockaddr_ipx *)sadr )->sa_socket = 0;
		copy[2] = 0;
		DO( 0, sa_netnum[0] );
		DO( 2, sa_netnum[1] );
		DO( 4, sa_netnum[2] );
		DO( 6, sa_netnum[3] );
		DO( 9, sa_nodenum[0] );
		DO( 11, sa_nodenum[1] );
		DO( 13, sa_nodenum[2] );
		DO( 15, sa_nodenum[3] );
		DO( 17, sa_nodenum[4] );
		DO( 19, sa_nodenum[5] );
	} else {
		( (struct sockaddr_in *)sadr )->sin_family = AF_INET;
		( (struct sockaddr_in *)sadr )->sin_port = 0;

#if defined RTCW_SP
		if ( Q_isnumeric( s[0] ) ) {
#else
		if ( s[0] >= '0' && s[0] <= '9' ) {
#endif // RTCW_XX

			*(int *)&( (struct sockaddr_in *)sadr )->sin_addr = inet_addr( s );
		} else {
			if ( ( h = gethostbyname( s ) ) == 0 ) {
				return 0;
			}
			*(int *)&( (struct sockaddr_in *)sadr )->sin_addr = *(int *)h->h_addr_list[0];
		}
	}

	return qtrue;
}

#undef DO

/*
=============
Sys_StringToAdr

idnewt
192.246.40.70
=============
*/
qboolean Sys_StringToAdr( const char *s, netadr_t *a ) {
	struct sockaddr sadr;

	if ( !Sys_StringToSockaddr( s, &sadr ) ) {
		return qfalse;
	}

	SockadrToNetadr( &sadr, a );
	return qtrue;
}

//=============================================================================

/*
==================
Sys_GetPacket

Never called by the game logic, just the system event queing
==================
*/
int recvfromCount;

qboolean Sys_GetPacket( netadr_t *net_from, msg_t *net_message ) {
	int ret;
	struct sockaddr from;
	int fromlen;
	int net_socket;
	int protocol;
	int err;

	for ( protocol = 0 ; protocol < 2 ; protocol++ ) {
		if ( protocol == 0 ) {
			net_socket = ip_socket;
		} else {
			net_socket = ipx_socket;
		}

		if ( !net_socket ) {
			continue;
		}

		fromlen = sizeof( from );
		recvfromCount++;        // performance check
		ret = recvfrom( net_socket, reinterpret_cast<char*> (net_message->data), net_message->maxsize, 0, (struct sockaddr *)&from, &fromlen );
		if ( ret == SOCKET_ERROR ) {
			err = WSAGetLastError();

			if ( err == WSAEWOULDBLOCK || err == WSAECONNRESET ) {
				continue;
			}
			Com_Printf( "NET_GetPacket: %s\n", NET_ErrorString() );
			continue;
		}

		if ( net_socket == ip_socket ) {
			memset( ( (struct sockaddr_in *)&from )->sin_zero, 0, 8 );
		}

		if ( usingSocks && net_socket == ip_socket && memcmp( &from, &socksRelayAddr, fromlen ) == 0 ) {
			if ( ret < 10 || net_message->data[0] != 0 || net_message->data[1] != 0 || net_message->data[2] != 0 || net_message->data[3] != 1 ) {
				continue;
			}
			net_from->type = NA_IP;
			net_from->ip[0] = net_message->data[4];
			net_from->ip[1] = net_message->data[5];
			net_from->ip[2] = net_message->data[6];
			net_from->ip[3] = net_message->data[7];
			net_from->port = *(short *)&net_message->data[8];
			net_message->readcount = 10;
		} else {
			SockadrToNetadr( &from, net_from );
			net_message->readcount = 0;
		}

		if ( ret == net_message->maxsize ) {
			Com_Printf( "Oversize packet from %s\n", NET_AdrToString( *net_from ) );
			continue;
		}

		net_message->cursize = ret;
		return qtrue;
	}

	return qfalse;
}

//=============================================================================

static char socksBuf[4096];

/*
==================
Sys_SendPacket
==================
*/
void Sys_SendPacket( int length, const void *data, netadr_t to ) {
	int ret;
	struct sockaddr addr;
	SOCKET net_socket;

	if ( to.type == NA_BROADCAST ) {
		net_socket = ip_socket;
	} else if ( to.type == NA_IP )    {
		net_socket = ip_socket;
	} else if ( to.type == NA_IPX )    {
		net_socket = ipx_socket;
	} else if ( to.type == NA_BROADCAST_IPX )    {
		net_socket = ipx_socket;
	} else {
		Com_Error( ERR_FATAL, "Sys_SendPacket: bad address type" );
		return;
	}

	if ( !net_socket ) {
		return;
	}

	NetadrToSockadr( &to, &addr );

	if ( usingSocks && to.type == NA_IP ) {
		socksBuf[0] = 0;    // reserved
		socksBuf[1] = 0;
		socksBuf[2] = 0;    // fragment (not fragmented)
		socksBuf[3] = 1;    // address type: IPV4
		*(int *)&socksBuf[4] = ( (struct sockaddr_in *)&addr )->sin_addr.s_addr;
		*(short *)&socksBuf[8] = ( (struct sockaddr_in *)&addr )->sin_port;
		memcpy( &socksBuf[10], data, length );
		ret = sendto( net_socket, socksBuf, length + 10, 0, &socksRelayAddr, sizeof( socksRelayAddr ) );
	} else {
		ret = sendto( net_socket, static_cast<const char*> (data), length, 0, &addr, sizeof( addr ) );
	}
	if ( ret == SOCKET_ERROR ) {
		int err = WSAGetLastError();

		// wouldblock is silent
		if ( err == WSAEWOULDBLOCK ) {
			return;
		}

		// some PPP links do not allow broadcasts and return an error
		if ( ( err == WSAEADDRNOTAVAIL ) && ( ( to.type == NA_BROADCAST ) || ( to.type == NA_BROADCAST_IPX ) ) ) {
			return;
		}

		Com_Printf( "NET_SendPacket: %s\n", NET_ErrorString() );
	}
}