/* * sdl_net.c - Q3Base SDL network glue * * Copyright (C) 2005 Ed Schouten * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "SDL_net.h" #include "../game/q_shared.h" #include "../qcommon/qcommon.h" static UDPsocket sock; /* * NET_Init: Initialise the network layer */ void NET_Init () { int port, i; /* Don't start when UDP is disabled */ if (Cvar_Get ("net_noudp", "0", 0)->value) return; /* Initialise SDL */ SDLNet_Init (); port = Cvar_Get ("net_port", va ("%i", PORT_SERVER), 0)->value; /* Try to find a free port */ for (i = 0; (i < 10) && !sock; i++) sock = SDLNet_UDP_Open (port + i); if (sock) /* Store the port number */ Cvar_SetValue ("net_port", port + i - 1); else /* No free ports left */ Com_Error (ERR_FATAL, "No free sockets available"); } /* * NET_Shutdown: Shutdown the network layer */ void NET_Shutdown () { /* Close our socket, if any */ if (sock) SDLNet_UDP_Close (sock); /* Shutdown SDL */ SDLNet_Quit (); } /* * NET_Restart: Restart the network layer */ void NET_Restart () { NET_Shutdown (); NET_Init (); } /* * Sys_SendPacket: Send a network packet */ void Sys_SendPacket (int length, const void *data, netadr_t to) { UDPpacket *packet; if (!sock) return; /* We can only handle IP packets */ if ((to.type != NA_IP) && (to.type != NA_BROADCAST)) return; packet = SDLNet_AllocPacket (length); /* Set our target */ packet->address.host = *(Uint32*)&to.ip; packet->address.port = to.port; /* Copy the data to the packet */ memcpy (packet->data, data, length); packet->len = length; /* And go! */ SDLNet_UDP_Send (sock, -1, packet); SDLNet_FreePacket (packet); } /* * Sys_GetPacket: Receive a network packet */ qboolean Sys_GetPacket (netadr_t *net_from, msg_t *net_message) { int ret; UDPpacket *packet; if (!sock) return qfalse; packet = SDLNet_AllocPacket (net_message->maxsize); ret = SDLNet_UDP_Recv (sock, packet); if (ret != 1) { /* Receive error or no packet available */ SDLNet_FreePacket (packet); return qfalse; } /* Copy address from the packet */ *(Uint32*)&net_from->ip = packet->address.host; net_from->port = packet->address.port; net_from->type = NA_IP; /* Copy data from the packet */ memcpy (net_message->data, packet->data, packet->len); net_message->cursize = packet->len; net_message->readcount = 0; SDLNet_FreePacket (packet); return qtrue; } /* * Sys_IsLANAddress: Check whether the address is in our current network */ qboolean Sys_IsLANAddress (netadr_t adr) { /* Loopback and IPX must imply LAN traffic */ if ((adr.type == NA_LOOPBACK) || (adr.type == NA_IPX)) return qtrue; /* Other protocols probably not */ if (adr.type != NA_IP) return qfalse; /* Class A - 10.0.0.0/8 */ if (adr.ip[0] == 0x0a) return qtrue; /* Class B 172.16.0.0/12 */ if ((adr.ip[0] == 0xac) && ((adr.ip[1] & 0xf0) == 0x10)) return qtrue; /* Class C 192.168.0.0/16 */ if ((adr.ip[0] == 0xc0) && (adr.ip[1] == 0xa8)) return qtrue; return qfalse; } /* * Sys_StringToAdr: Resolve an IP address using DNS */ qboolean Sys_StringToAdr (const char *s, netadr_t *a) { IPaddress addr; /* Try to resolve it */ if (SDLNet_ResolveHost (&addr, s, a->port) != 0) return qfalse; /* Copy the address back to the structure */ *(Uint32*)&a->ip = addr.host; a->type = NA_IP; return qtrue; } /* * NET_Sleep: Sleep for a specified period of time or until the socket * is ready - Not implemented */ void NET_Sleep (int msec) { } /* * Sys_ShowIP: Print the IP address that is used - Not implemented */ void Sys_ShowIP () { }