00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "../game/q_shared.h"
00025 #include "../qcommon/qcommon.h"
00026
00027 #include <unistd.h>
00028 #include <sys/socket.h>
00029 #include <sys/time.h>
00030 #include <netinet/in.h>
00031 #include <netdb.h>
00032 #include <arpa/inet.h>
00033
00034 #include <sys/param.h>
00035 #include <sys/ioctl.h>
00036 #include <sys/uio.h>
00037 #include <errno.h>
00038
00039 #ifdef MACOS_X
00040 #import <sys/sockio.h>
00041 #import <net/if.h>
00042 #import <net/if_types.h>
00043
00044 #import <arpa/inet.h>
00045 #import <net/if_dl.h>
00046 #endif
00047
00048 static cvar_t *noudp;
00049
00050 netadr_t net_local_adr;
00051
00052 int ip_socket;
00053 int ipx_socket;
00054
00055 #define MAX_IPS 16
00056 static int numIP;
00057 static byte localIP[MAX_IPS][4];
00058
00059 int NET_Socket (char *net_interface, int port);
00060 char *NET_ErrorString (void);
00061
00062
00063
00064 void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s)
00065 {
00066 memset (s, 0, sizeof(*s));
00067
00068 if (a->type == NA_BROADCAST)
00069 {
00070 s->sin_family = AF_INET;
00071
00072 s->sin_port = a->port;
00073 *(int *)&s->sin_addr = -1;
00074 }
00075 else if (a->type == NA_IP)
00076 {
00077 s->sin_family = AF_INET;
00078
00079 *(int *)&s->sin_addr = *(int *)&a->ip;
00080 s->sin_port = a->port;
00081 }
00082 }
00083
00084 void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a)
00085 {
00086 *(int *)&a->ip = *(int *)&s->sin_addr;
00087 a->port = s->sin_port;
00088 a->type = NA_IP;
00089 }
00090
00091 char *NET_BaseAdrToString (netadr_t a)
00092 {
00093 static char s[64];
00094
00095 Com_sprintf (s, sizeof(s), "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
00096
00097 return s;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 qboolean Sys_StringToSockaddr (const char *s, struct sockaddr *sadr)
00109 {
00110 struct hostent *h;
00111
00112
00113 memset (sadr, 0, sizeof(*sadr));
00114 ((struct sockaddr_in *)sadr)->sin_family = AF_INET;
00115
00116 ((struct sockaddr_in *)sadr)->sin_port = 0;
00117
00118 if ( s[0] >= '0' && s[0] <= '9')
00119 {
00120 *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(s);
00121 }
00122 else
00123 {
00124 if (! (h = gethostbyname(s)) )
00125 return qfalse;
00126 *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0];
00127 }
00128
00129 return qtrue;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 qboolean Sys_StringToAdr (const char *s, netadr_t *a)
00144 {
00145 struct sockaddr_in sadr;
00146
00147 if (!Sys_StringToSockaddr (s, (struct sockaddr *)&sadr))
00148 return qfalse;
00149
00150 SockadrToNetadr (&sadr, a);
00151
00152 return qtrue;
00153 }
00154
00155
00156
00157
00158 qboolean Sys_GetPacket (netadr_t *net_from, msg_t *net_message)
00159 {
00160 int ret;
00161 struct sockaddr_in from;
00162 int fromlen;
00163 int net_socket;
00164 int protocol;
00165 int err;
00166
00167 for (protocol = 0 ; protocol < 2 ; protocol++)
00168 {
00169 if (protocol == 0)
00170 net_socket = ip_socket;
00171 else
00172 net_socket = ipx_socket;
00173
00174 if (!net_socket)
00175 continue;
00176
00177 fromlen = sizeof(from);
00178 ret = recvfrom (net_socket, net_message->data, net_message->maxsize
00179 , 0, (struct sockaddr *)&from, &fromlen);
00180
00181 SockadrToNetadr (&from, net_from);
00182
00183 net_message->readcount = 0;
00184
00185 if (ret == -1)
00186 {
00187 err = errno;
00188
00189 if (err == EWOULDBLOCK || err == ECONNREFUSED)
00190 continue;
00191 Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
00192 NET_AdrToString(*net_from));
00193 continue;
00194 }
00195
00196 if (ret == net_message->maxsize)
00197 {
00198 Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from));
00199 continue;
00200 }
00201
00202 net_message->cursize = ret;
00203 return qtrue;
00204 }
00205
00206 return qfalse;
00207 }
00208
00209
00210
00211 void Sys_SendPacket( int length, const void *data, netadr_t to )
00212 {
00213 int ret;
00214 struct sockaddr_in addr;
00215 int net_socket;
00216
00217 if (to.type == NA_BROADCAST)
00218 {
00219 net_socket = ip_socket;
00220 }
00221 else if (to.type == NA_IP)
00222 {
00223 net_socket = ip_socket;
00224 }
00225 else if (to.type == NA_IPX)
00226 {
00227 net_socket = ipx_socket;
00228 }
00229 else if (to.type == NA_BROADCAST_IPX)
00230 {
00231 net_socket = ipx_socket;
00232 }
00233 else {
00234 Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
00235 return;
00236 }
00237
00238 if (!net_socket)
00239 return;
00240
00241 NetadrToSockadr (&to, &addr);
00242
00243 ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
00244 if (ret == -1)
00245 {
00246 Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
00247 NET_AdrToString (to));
00248 }
00249 }
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 qboolean Sys_IsLANAddress (netadr_t adr) {
00262 int i;
00263
00264 if( adr.type == NA_LOOPBACK ) {
00265 return qtrue;
00266 }
00267
00268 if( adr.type == NA_IPX ) {
00269 return qtrue;
00270 }
00271
00272 if( adr.type != NA_IP ) {
00273 return qfalse;
00274 }
00275
00276
00277
00278
00279
00280 if( (adr.ip[0] & 0x80) == 0x00 ) {
00281 for ( i = 0 ; i < numIP ; i++ ) {
00282 if( adr.ip[0] == localIP[i][0] ) {
00283 return qtrue;
00284 }
00285 }
00286
00287 return qfalse;
00288 }
00289
00290
00291 if( (adr.ip[0] & 0xc0) == 0x80 ) {
00292 for ( i = 0 ; i < numIP ; i++ ) {
00293 if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] ) {
00294 return qtrue;
00295 }
00296
00297 if( adr.ip[0] == 172 && localIP[i][0] == 172 && (adr.ip[1] & 0xf0) == 16 && (localIP[i][1] & 0xf0) == 16 ) {
00298 return qtrue;
00299 }
00300 }
00301 return qfalse;
00302 }
00303
00304
00305 for ( i = 0 ; i < numIP ; i++ ) {
00306 if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] && adr.ip[2] == localIP[i][2] ) {
00307 return qtrue;
00308 }
00309
00310 if( adr.ip[0] == 192 && localIP[i][0] == 192 && adr.ip[1] == 168 && localIP[i][1] == 168 ) {
00311 return qtrue;
00312 }
00313 }
00314 return qfalse;
00315 }
00316
00317
00318
00319
00320
00321
00322 void Sys_ShowIP(void) {
00323 int i;
00324
00325 for (i = 0; i < numIP; i++) {
00326 Com_Printf( "IP: %i.%i.%i.%i\n", localIP[i][0], localIP[i][1], localIP[i][2], localIP[i][3] );
00327 }
00328 }
00329
00330
00331
00332
00333
00334
00335 #ifdef MACOS_X
00336
00337
00338
00339 #define IFR_NEXT(ifr) \
00340 ((struct ifreq *) ((char *) (ifr) + sizeof(*(ifr)) + \
00341 MAX(0, (int) (ifr)->ifr_addr.sa_len - (int) sizeof((ifr)->ifr_addr))))
00342
00343 void NET_GetLocalAddress( void ) {
00344 struct ifreq requestBuffer[MAX_IPS], *linkInterface, *inetInterface;
00345 struct ifconf ifc;
00346 struct ifreq ifr;
00347 struct sockaddr_dl *sdl;
00348 int interfaceSocket;
00349 int family;
00350
00351
00352
00353
00354 numIP = 0;
00355
00356 ifc.ifc_len = sizeof(requestBuffer);
00357 ifc.ifc_buf = (caddr_t)requestBuffer;
00358
00359
00360 family = AF_INET;
00361 if ((interfaceSocket = socket(family, SOCK_DGRAM, 0)) < 0) {
00362 Com_Printf("NET_GetLocalAddress: Unable to create temporary socket, errno = %d\n", errno);
00363 return;
00364 }
00365
00366 if (ioctl(interfaceSocket, SIOCGIFCONF, &ifc) != 0) {
00367 Com_Printf("NET_GetLocalAddress: Unable to get list of network interfaces, errno = %d\n", errno);
00368 return;
00369 }
00370
00371
00372 linkInterface = (struct ifreq *) ifc.ifc_buf;
00373 while ((char *) linkInterface < &ifc.ifc_buf[ifc.ifc_len]) {
00374 unsigned int nameLength;
00375
00376
00377
00378
00379 if (linkInterface->ifr_addr.sa_family == AF_LINK) {
00380
00381 inetInterface = (struct ifreq *) ifc.ifc_buf;
00382 while ((char *) inetInterface < &ifc.ifc_buf[ifc.ifc_len]) {
00383 if (inetInterface->ifr_addr.sa_family == AF_INET &&
00384 !strncmp(inetInterface->ifr_name, linkInterface->ifr_name, sizeof(linkInterface->ifr_name))) {
00385
00386 for (nameLength = 0; nameLength < IFNAMSIZ; nameLength++)
00387 if (!linkInterface->ifr_name[nameLength])
00388 break;
00389
00390 sdl = (struct sockaddr_dl *)&linkInterface->ifr_addr;
00391
00392 if (sdl->sdl_type != IFT_LOOP) {
00393
00394 strncpy(ifr.ifr_name, inetInterface->ifr_name, sizeof(ifr.ifr_name));
00395 if (ioctl(interfaceSocket, OSIOCGIFADDR, (caddr_t)&ifr) < 0) {
00396 Com_Printf("NET_GetLocalAddress: Unable to get local address for interface '%s', errno = %d\n", inetInterface->ifr_name, errno);
00397 } else {
00398 struct sockaddr_in *sin;
00399 int ip;
00400
00401 sin = (struct sockaddr_in *)&ifr.ifr_addr;
00402
00403 ip = ntohl(sin->sin_addr.s_addr);
00404 localIP[ numIP ][0] = (ip >> 24) & 0xff;
00405 localIP[ numIP ][1] = (ip >> 16) & 0xff;
00406 localIP[ numIP ][2] = (ip >> 8) & 0xff;
00407 localIP[ numIP ][3] = (ip >> 0) & 0xff;
00408 Com_Printf( "IP: %i.%i.%i.%i (%s)\n", localIP[ numIP ][0], localIP[ numIP ][1], localIP[ numIP ][2], localIP[ numIP ][3], inetInterface->ifr_name);
00409 numIP++;
00410 }
00411 }
00412
00413
00414
00415
00416
00417 }
00418 inetInterface = IFR_NEXT(inetInterface);
00419 }
00420 }
00421 linkInterface = IFR_NEXT(linkInterface);
00422 }
00423
00424 close(interfaceSocket);
00425 }
00426
00427 #else
00428 void NET_GetLocalAddress( void ) {
00429 char hostname[256];
00430 struct hostent *hostInfo;
00431
00432 char *p;
00433 int ip;
00434 int n;
00435
00436 if ( gethostname( hostname, 256 ) == -1 ) {
00437 return;
00438 }
00439
00440 hostInfo = gethostbyname( hostname );
00441 if ( !hostInfo ) {
00442 return;
00443 }
00444
00445 Com_Printf( "Hostname: %s\n", hostInfo->h_name );
00446 n = 0;
00447 while( ( p = hostInfo->h_aliases[n++] ) != NULL ) {
00448 Com_Printf( "Alias: %s\n", p );
00449 }
00450
00451 if ( hostInfo->h_addrtype != AF_INET ) {
00452 return;
00453 }
00454
00455 numIP = 0;
00456 while( ( p = hostInfo->h_addr_list[numIP++] ) != NULL && numIP < MAX_IPS ) {
00457 ip = ntohl( *(int *)p );
00458 localIP[ numIP ][0] = p[0];
00459 localIP[ numIP ][1] = p[1];
00460 localIP[ numIP ][2] = p[2];
00461 localIP[ numIP ][3] = p[3];
00462 Com_Printf( "IP: %i.%i.%i.%i\n", ( ip >> 24 ) & 0xff, ( ip >> 16 ) & 0xff, ( ip >> 8 ) & 0xff, ip & 0xff );
00463 }
00464 }
00465 #endif
00466
00467
00468
00469
00470
00471
00472
00473 int NET_IPSocket (char *net_interface, int port);
00474 void NET_OpenIP (void)
00475 {
00476 cvar_t *ip;
00477 int port;
00478 int i;
00479
00480 ip = Cvar_Get ("net_ip", "localhost", 0);
00481
00482 port = Cvar_Get("net_port", va("%i", PORT_SERVER), 0)->value;
00483
00484 for ( i = 0 ; i < 10 ; i++ ) {
00485 ip_socket = NET_IPSocket (ip->string, port + i);
00486 if ( ip_socket ) {
00487 Cvar_SetValue( "net_port", port + i );
00488 NET_GetLocalAddress();
00489 return;
00490 }
00491 }
00492 Com_Error (ERR_FATAL, "Couldn't allocate IP port");
00493 }
00494
00495
00496
00497
00498
00499
00500
00501 void NET_Init (void)
00502 {
00503 noudp = Cvar_Get ("net_noudp", "0", 0);
00504
00505 if (! noudp->value) {
00506 NET_OpenIP ();
00507 }
00508 }
00509
00510
00511
00512
00513
00514
00515
00516 int NET_IPSocket (char *net_interface, int port)
00517 {
00518 int newsocket;
00519 struct sockaddr_in address;
00520 qboolean _qtrue = qtrue;
00521 int i = 1;
00522
00523 if ( net_interface ) {
00524 Com_Printf("Opening IP socket: %s:%i\n", net_interface, port );
00525 } else {
00526 Com_Printf("Opening IP socket: localhost:%i\n", port );
00527 }
00528
00529 if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
00530 {
00531 Com_Printf ("ERROR: UDP_OpenSocket: socket: %s", NET_ErrorString());
00532 return 0;
00533 }
00534
00535
00536 if (ioctl (newsocket, FIONBIO, &_qtrue) == -1)
00537 {
00538 Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString());
00539 return 0;
00540 }
00541
00542
00543 if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
00544 {
00545 Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString());
00546 return 0;
00547 }
00548
00549 if (!net_interface || !net_interface[0] || !Q_stricmp(net_interface, "localhost"))
00550 address.sin_addr.s_addr = INADDR_ANY;
00551 else
00552 Sys_StringToSockaddr (net_interface, (struct sockaddr *)&address);
00553
00554 if (port == PORT_ANY)
00555 address.sin_port = 0;
00556 else
00557 address.sin_port = htons((short)port);
00558
00559 address.sin_family = AF_INET;
00560
00561 if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
00562 {
00563 Com_Printf ("ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString());
00564 close (newsocket);
00565 return 0;
00566 }
00567
00568 return newsocket;
00569 }
00570
00571
00572
00573
00574
00575
00576 void NET_Shutdown (void)
00577 {
00578 if (ip_socket) {
00579 close(ip_socket);
00580 ip_socket = 0;
00581 }
00582 }
00583
00584
00585
00586
00587
00588
00589
00590 char *NET_ErrorString (void)
00591 {
00592 int code;
00593
00594 code = errno;
00595 return strerror (code);
00596 }
00597
00598
00599 void NET_Sleep(int msec)
00600 {
00601 struct timeval timeout;
00602 fd_set fdset;
00603 extern qboolean stdin_active;
00604
00605 if (!ip_socket || !com_dedicated->integer)
00606 return;
00607
00608 FD_ZERO(&fdset);
00609 if (stdin_active)
00610 FD_SET(0, &fdset);
00611 FD_SET(ip_socket, &fdset);
00612 timeout.tv_sec = msec/1000;
00613 timeout.tv_usec = (msec%1000)*1000;
00614 select(ip_socket+1, &fdset, NULL, NULL, &timeout);
00615 }
00616