Home | History | Annotate | Download | only in jni
      1 /*
      2 Copyright (C) 1996-1997 Id Software, Inc.
      3 
      4 This program is free software; you can redistribute it and/or
      5 modify it under the terms of the GNU General Public License
      6 as published by the Free Software Foundation; either version 2
      7 of the License, or (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     12 
     13 See the GNU General Public License for more details.
     14 
     15 You should have received a copy of the GNU General Public License
     16 along with this program; if not, write to the Free Software
     17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     18 
     19 */
     20 // net_udp.c
     21 
     22 #include "quakedef.h"
     23 
     24 #include <sys/types.h>
     25 #include <sys/socket.h>
     26 #include <netinet/in.h>
     27 #include <netdb.h>
     28 #include <sys/param.h>
     29 #include <sys/ioctl.h>
     30 #include <errno.h>
     31 #include <unistd.h>
     32 
     33 #include <arpa/inet.h>
     34 
     35 #ifdef __sun__
     36 #include <sys/filio.h>
     37 #endif
     38 
     39 #ifdef NeXT
     40 #include <libc.h>
     41 #endif
     42 
     43 extern cvar_t hostname;
     44 
     45 static int net_acceptsocket = -1;		// socket for fielding new connections
     46 static int net_controlsocket;
     47 static int net_broadcastsocket = 0;
     48 static struct qsockaddr broadcastaddr;
     49 
     50 static unsigned long myAddr;
     51 
     52 #include "net_udp.h"
     53 
     54 // **** Start of Android-specific code ****
     55 // copied from ifc_utils.c
     56 //
     57 // This isn't a good long-term solution:
     58 // 1) It is hard-wired to a particular wireless driver
     59 // 2) It doesn't handle the IP address changing over time
     60 
     61 #include <sys/ioctl.h>
     62 #include <net/if.h>
     63 
     64 static int ifc_ctl_sock = -1;
     65 
     66 int ifc_init(void)
     67 {
     68     if (ifc_ctl_sock == -1) {
     69         ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
     70         if (ifc_ctl_sock < 0) {
     71         	Con_Printf("socket() failed: %s\n", strerror(errno));
     72         }
     73     }
     74     return ifc_ctl_sock < 0 ? -1 : 0;
     75 }
     76 
     77 void ifc_close(void)
     78 {
     79     if (ifc_ctl_sock != -1) {
     80         (void)close(ifc_ctl_sock);
     81         ifc_ctl_sock = -1;
     82     }
     83 }
     84 
     85 static void ifc_init_ifr(const char *name, struct ifreq *ifr)
     86 {
     87     memset(ifr, 0, sizeof(struct ifreq));
     88     strncpy(ifr->ifr_name, name, IFNAMSIZ);
     89     ifr->ifr_name[IFNAMSIZ - 1] = 0;
     90 }
     91 
     92 int ifc_get_info(const char *name, in_addr_t *addr, in_addr_t *mask, unsigned *flags)
     93 {
     94     struct ifreq ifr;
     95     ifc_init_ifr(name, &ifr);
     96 
     97     if (addr != NULL) {
     98         if(ioctl(ifc_ctl_sock, SIOCGIFADDR, &ifr) < 0) {
     99             *addr = 0;
    100         } else {
    101             *addr = ((struct sockaddr_in*) (void*) &ifr.ifr_addr)->sin_addr.s_addr;
    102         }
    103     }
    104 
    105     if (mask != NULL) {
    106         if(ioctl(ifc_ctl_sock, SIOCGIFNETMASK, &ifr) < 0) {
    107             *mask = 0;
    108         } else {
    109             *mask = ((struct sockaddr_in*) (void*) &ifr.ifr_addr)->sin_addr.s_addr;
    110         }
    111     }
    112 
    113     if (flags != NULL) {
    114         if(ioctl(ifc_ctl_sock, SIOCGIFFLAGS, &ifr) < 0) {
    115             *flags = 0;
    116         } else {
    117             *flags = ifr.ifr_flags;
    118         }
    119     }
    120 
    121     return 0;
    122 }
    123 
    124 void AndroidGetAddr() {
    125 	if (ifc_init()) {
    126 		return;
    127 	}
    128 	in_addr_t addr;
    129 	ifc_get_info("tiwlan0", &addr, 0, 0);
    130 	myAddr = addr;
    131 	ifc_close();
    132 }
    133 
    134 
    135 // **** End of Android-specific code ****
    136 
    137 //=============================================================================
    138 
    139 int UDP_Init (void)
    140 {
    141 	struct hostent *local;
    142 	char	buff[MAXHOSTNAMELEN];
    143 	struct qsockaddr addr;
    144 	char *colon;
    145 
    146 	if (COM_CheckParm ("-noudp"))
    147 		return -1;
    148 
    149 #if 1 // Android
    150 	AndroidGetAddr();
    151 #else
    152 	// determine my name & address
    153 	gethostname(buff, MAXHOSTNAMELEN);
    154 	local = gethostbyname(buff);
    155 
    156 	if(!local)
    157 	{
    158 		Con_Printf("Could not gethostbyname(\"%s\")\n", buff);
    159 		return -1;
    160 	}
    161 
    162 	myAddr = *(int *)local->h_addr_list[0];
    163 
    164 	// if the quake hostname isn't set, set it to the machine name
    165 	if (Q_strcmp(hostname.string, "UNNAMED") == 0)
    166 	{
    167 		buff[15] = 0;
    168 		Cvar_Set ("hostname", buff);
    169 	}
    170 #endif
    171 	if ((net_controlsocket = UDP_OpenSocket (0)) == -1)
    172 		Sys_Error("UDP_Init: Unable to open control socket\n");
    173 
    174 	sockaddr_in temp;
    175 
    176 	memcpy(&temp, &broadcastaddr, sizeof(temp));
    177 
    178 	temp.sin_family = AF_INET;
    179 	temp.sin_addr.s_addr = INADDR_BROADCAST;
    180 	temp.sin_port = htons(net_hostport);
    181 
    182 	memcpy(&broadcastaddr, &temp, sizeof(temp));
    183 
    184 	UDP_GetSocketAddr (net_controlsocket, &addr);
    185 	Q_strcpy(my_tcpip_address,  UDP_AddrToString (&addr));
    186 	colon = Q_strrchr (my_tcpip_address, ':');
    187 	if (colon)
    188 		*colon = 0;
    189 
    190 	Con_Printf("UDP Initialized\n");
    191 	tcpipAvailable = true;
    192 
    193 	return net_controlsocket;
    194 }
    195 
    196 //=============================================================================
    197 
    198 void UDP_Shutdown (void)
    199 {
    200 	UDP_Listen (false);
    201 	UDP_CloseSocket (net_controlsocket);
    202 }
    203 
    204 //=============================================================================
    205 
    206 void UDP_Listen (qboolean state)
    207 {
    208 	// enable listening
    209 	if (state)
    210 	{
    211 		if (net_acceptsocket != -1)
    212 			return;
    213 		if ((net_acceptsocket = UDP_OpenSocket (net_hostport)) == -1)
    214 			Sys_Error ("UDP_Listen: Unable to open accept socket\n");
    215 		return;
    216 	}
    217 
    218 	// disable listening
    219 	if (net_acceptsocket == -1)
    220 		return;
    221 	UDP_CloseSocket (net_acceptsocket);
    222 	net_acceptsocket = -1;
    223 }
    224 
    225 //=============================================================================
    226 
    227 int UDP_OpenSocket (int port)
    228 {
    229 	int newsocket;
    230 	union {
    231 	    struct sockaddr_in in;
    232 	    struct sockaddr sockaddr;
    233 	} address;
    234 	qboolean _true = true;
    235 
    236 	if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    237 		return -1;
    238 
    239 	if (ioctl (newsocket, FIONBIO, (char *)&_true) == -1)
    240 		goto ErrorReturn;
    241 
    242 	address.in.sin_family = AF_INET;
    243 	address.in.sin_addr.s_addr = INADDR_ANY;
    244 	address.in.sin_port = htons(port);
    245 	if( bind (newsocket, &address.sockaddr, sizeof(address.in)) == -1)
    246 		goto ErrorReturn;
    247 
    248 	return newsocket;
    249 
    250 ErrorReturn:
    251 	close (newsocket);
    252 	return -1;
    253 }
    254 
    255 //=============================================================================
    256 
    257 int UDP_CloseSocket (int socket)
    258 {
    259 	if (socket == net_broadcastsocket)
    260 		net_broadcastsocket = 0;
    261 	return close (socket);
    262 }
    263 
    264 
    265 //=============================================================================
    266 /*
    267 ============
    268 PartialIPAddress
    269 
    270 this lets you type only as much of the net address as required, using
    271 the local network components to fill in the rest
    272 ============
    273 */
    274 static int PartialIPAddress (const char *in, struct qsockaddr *hostaddr)
    275 {
    276 	char buff[256];
    277 	char *b;
    278 	int addr;
    279 	int num;
    280 	int mask;
    281 	int run;
    282 	int port;
    283 
    284 	buff[0] = '.';
    285 	b = buff;
    286 	strcpy(buff+1, in);
    287 	if (buff[1] == '.')
    288 		b++;
    289 
    290 	addr = 0;
    291 	mask=-1;
    292 	while (*b == '.')
    293 	{
    294 		b++;
    295 		num = 0;
    296 		run = 0;
    297 		while (!( *b < '0' || *b > '9'))
    298 		{
    299 		  num = num*10 + *b++ - '0';
    300 		  if (++run > 3)
    301 		  	return -1;
    302 		}
    303 		if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0)
    304 			return -1;
    305 		if (num < 0 || num > 255)
    306 			return -1;
    307 		mask<<=8;
    308 		addr = (addr<<8) + num;
    309 	}
    310 
    311 	if (*b++ == ':')
    312 		port = Q_atoi(b);
    313 	else
    314 		port = net_hostport;
    315 
    316 	hostaddr->sa_family = AF_INET;
    317 	((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port);
    318 	((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr);
    319 
    320 	return 0;
    321 }
    322 //=============================================================================
    323 
    324 int UDP_Connect (int socket, struct qsockaddr *addr)
    325 {
    326 	return 0;
    327 }
    328 
    329 //=============================================================================
    330 
    331 int UDP_CheckNewConnections (void)
    332 {
    333 	unsigned long	available;
    334 
    335 	if (net_acceptsocket == -1)
    336 		return -1;
    337 
    338 	if (ioctl (net_acceptsocket, FIONREAD, &available) == -1)
    339 		Sys_Error ("UDP: ioctlsocket (FIONREAD) failed\n");
    340 	if (available)
    341 		return net_acceptsocket;
    342 	return -1;
    343 }
    344 
    345 //=============================================================================
    346 
    347 int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr)
    348 {
    349 	int addrlen = sizeof (struct qsockaddr);
    350 	int ret;
    351 
    352 	ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, (socklen_t*) &addrlen);
    353 	if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED))
    354 		return 0;
    355 	return ret;
    356 }
    357 
    358 //=============================================================================
    359 
    360 int UDP_MakeSocketBroadcastCapable (int socket)
    361 {
    362 	int				i = 1;
    363 
    364 	// make this socket broadcast capable
    365 	if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0)
    366 		return -1;
    367 	net_broadcastsocket = socket;
    368 
    369 	return 0;
    370 }
    371 
    372 //=============================================================================
    373 
    374 int UDP_Broadcast (int socket, byte *buf, int len)
    375 {
    376 	int ret;
    377 
    378 	if (socket != net_broadcastsocket)
    379 	{
    380 		if (net_broadcastsocket != 0)
    381 			Sys_Error("Attempted to use multiple broadcasts sockets\n");
    382 		ret = UDP_MakeSocketBroadcastCapable (socket);
    383 		if (ret == -1)
    384 		{
    385 			Con_Printf("Unable to make socket broadcast capable\n");
    386 			return ret;
    387 		}
    388 	}
    389 
    390 	return UDP_Write (socket, buf, len, &broadcastaddr);
    391 }
    392 
    393 //=============================================================================
    394 
    395 int UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr)
    396 {
    397 	int ret;
    398 
    399 	ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr));
    400 	if (ret == -1 && errno == EWOULDBLOCK)
    401 		return 0;
    402 	return ret;
    403 }
    404 
    405 //=============================================================================
    406 
    407 char *UDP_AddrToString (struct qsockaddr *addr)
    408 {
    409 	static char buffer[22];
    410 	int haddr;
    411 
    412 	haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
    413 	sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, ntohs(((struct sockaddr_in *)addr)->sin_port));
    414 	return buffer;
    415 }
    416 
    417 //=============================================================================
    418 
    419 int UDP_StringToAddr (const char *string, struct qsockaddr *addr)
    420 {
    421 	int ha1, ha2, ha3, ha4, hp;
    422 	int ipaddr;
    423 
    424 	sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
    425 	ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
    426 
    427 	addr->sa_family = AF_INET;
    428 	((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
    429 	((struct sockaddr_in *)addr)->sin_port = htons(hp);
    430 	return 0;
    431 }
    432 
    433 //=============================================================================
    434 
    435 int UDP_GetSocketAddr (int socket, struct qsockaddr *addr)
    436 {
    437 	int addrlen = sizeof(struct qsockaddr);
    438 	unsigned int a;
    439 
    440 	Q_memset(addr, 0, sizeof(struct qsockaddr));
    441 	getsockname(socket, (struct sockaddr *)addr, (socklen_t*) &addrlen);
    442 	a = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
    443 	if (a == 0 || (in_addr_t) a == inet_addr("127.0.0.1"))
    444 		((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr;
    445 
    446 	return 0;
    447 }
    448 
    449 //=============================================================================
    450 
    451 int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name)
    452 {
    453 	struct hostent *hostentry;
    454 
    455 	hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET);
    456 	if (hostentry)
    457 	{
    458 		Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1);
    459 		return 0;
    460 	}
    461 
    462 	Q_strcpy (name, UDP_AddrToString (addr));
    463 	return 0;
    464 }
    465 
    466 //=============================================================================
    467 
    468 int UDP_GetAddrFromName(const char *name, struct qsockaddr *addr)
    469 {
    470 	struct hostent *hostentry;
    471 
    472 	if (name[0] >= '0' && name[0] <= '9')
    473 		return PartialIPAddress (name, addr);
    474 
    475 	hostentry = gethostbyname (name);
    476 	if (!hostentry)
    477 		return -1;
    478 
    479 	addr->sa_family = AF_INET;
    480 	((struct sockaddr_in *)addr)->sin_port = htons(net_hostport);
    481 	((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
    482 
    483 	return 0;
    484 }
    485 
    486 //=============================================================================
    487 
    488 int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
    489 {
    490 	if (addr1->sa_family != addr2->sa_family)
    491 		return -1;
    492 
    493 	if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
    494 		return -1;
    495 
    496 	if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
    497 		return 1;
    498 
    499 	return 0;
    500 }
    501 
    502 //=============================================================================
    503 
    504 int UDP_GetSocketPort (struct qsockaddr *addr)
    505 {
    506 	return ntohs(((struct sockaddr_in *)addr)->sin_port);
    507 }
    508 
    509 
    510 int UDP_SetSocketPort (struct qsockaddr *addr, int port)
    511 {
    512 	((struct sockaddr_in *)addr)->sin_port = htons(port);
    513 	return 0;
    514 }
    515 
    516 //=============================================================================
    517