~ubuntu-branches/ubuntu/jaunty/openarena/jaunty

« back to all changes in this revision

Viewing changes to code/unix/unix_net.c

  • Committer: Bazaar Package Importer
  • Author(s): Bruno "Fuddl" Kleinert, Bruno "Fuddl" Kleinert
  • Date: 2008-04-24 14:33:54 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080424143354-0cuxsalv98ajw2js
Tags: 0.7.6-1
[ Bruno "Fuddl" Kleinert ]
* New upstream release
* Freshen 10_fix_build_and_binary_on_alpha.dpatch to apply to latest
  upstream sources
* Remove 10-fix_menudef.h_includes.dpatch which pulled in a missing header
  file. The header is now included in the upstream tarball.
* Remove debian/watch, because upstream places its new releases too often to
  different download locations
* Updated debian/copyright to reflect the download location
* Expand copyright years in debian/copyright

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
===========================================================================
3
 
Copyright (C) 1999-2005 Id Software, Inc.
4
 
 
5
 
This file is part of Quake III Arena source code.
6
 
 
7
 
Quake III Arena source code is free software; you can redistribute it
8
 
and/or modify it under the terms of the GNU General Public License as
9
 
published by the Free Software Foundation; either version 2 of the License,
10
 
or (at your option) any later version.
11
 
 
12
 
Quake III Arena source code is distributed in the hope that it will be
13
 
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
GNU General Public License for more details.
16
 
 
17
 
You should have received a copy of the GNU General Public License
18
 
along with Quake III Arena source code; if not, write to the Free Software
19
 
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
 
===========================================================================
21
 
*/
22
 
// unix_net.c
23
 
 
24
 
#include "../qcommon/q_shared.h"
25
 
#include "../qcommon/qcommon.h"
26
 
 
27
 
#include <unistd.h>
28
 
#if MAC_OS_X_VERSION_MIN_REQUIRED == 1020
29
 
  // needed for socket_t on OSX 10.2
30
 
  #define _BSD_SOCKLEN_T_
31
 
#endif
32
 
#include <sys/socket.h>
33
 
#include <sys/time.h>
34
 
#include <netinet/in.h>
35
 
#include <netdb.h>
36
 
#include <arpa/inet.h> // bk001204
37
 
 
38
 
#include <sys/param.h>
39
 
#include <sys/ioctl.h>
40
 
#include <sys/uio.h>
41
 
#include <errno.h>
42
 
 
43
 
#ifdef MACOS_X
44
 
#import <sys/sockio.h>
45
 
#import <net/if.h>
46
 
#import <net/if_types.h>
47
 
 
48
 
#import <arpa/inet.h>         // for inet_ntoa()
49
 
#import <net/if_dl.h>         // for 'struct sockaddr_dl'
50
 
#endif
51
 
 
52
 
#ifdef __sun
53
 
#include <sys/filio.h>
54
 
#endif
55
 
 
56
 
static cvar_t   *noudp;
57
 
 
58
 
netadr_t        net_local_adr;
59
 
 
60
 
int                     ip_socket;
61
 
int                     ipx_socket;
62
 
 
63
 
#define MAX_IPS         16
64
 
static  int             numIP;
65
 
static  byte    localIP[MAX_IPS][4];
66
 
 
67
 
int NET_Socket (char *net_interface, int port);
68
 
char *NET_ErrorString (void);
69
 
 
70
 
//=============================================================================
71
 
 
72
 
void NetadrToSockadr (netadr_t *a, struct sockaddr_in *s)
73
 
{
74
 
        memset (s, 0, sizeof(*s));
75
 
 
76
 
        if (a->type == NA_BROADCAST)
77
 
        {
78
 
                s->sin_family = AF_INET;
79
 
 
80
 
                s->sin_port = a->port;
81
 
                *(int *)&s->sin_addr = -1;
82
 
        }
83
 
        else if (a->type == NA_IP)
84
 
        {
85
 
                s->sin_family = AF_INET;
86
 
 
87
 
                *(int *)&s->sin_addr = *(int *)&a->ip;
88
 
                s->sin_port = a->port;
89
 
        }
90
 
}
91
 
 
92
 
void SockadrToNetadr (struct sockaddr_in *s, netadr_t *a)
93
 
{
94
 
        *(int *)&a->ip = *(int *)&s->sin_addr;
95
 
        a->port = s->sin_port;
96
 
        a->type = NA_IP;
97
 
}
98
 
 
99
 
char    *NET_BaseAdrToString (netadr_t a)
100
 
{
101
 
        static  char    s[64];
102
 
        
103
 
        Com_sprintf (s, sizeof(s), "%i.%i.%i.%i", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
104
 
 
105
 
        return s;
106
 
}
107
 
 
108
 
/*
109
 
=============
110
 
Sys_StringToAdr
111
 
 
112
 
idnewt
113
 
192.246.40.70
114
 
=============
115
 
*/
116
 
qboolean        Sys_StringToSockaddr (const char *s, struct sockaddr *sadr)
117
 
{
118
 
        struct hostent  *h;
119
 
        //char  *colon; // bk001204 - unused
120
 
        
121
 
        memset (sadr, 0, sizeof(*sadr));
122
 
        ((struct sockaddr_in *)sadr)->sin_family = AF_INET;
123
 
        
124
 
        ((struct sockaddr_in *)sadr)->sin_port = 0;
125
 
        
126
 
        if ( s[0] >= '0' && s[0] <= '9')
127
 
        {
128
 
                *(int *)&((struct sockaddr_in *)sadr)->sin_addr = inet_addr(s);
129
 
        }
130
 
        else
131
 
        {
132
 
                if (! (h = gethostbyname(s)) )
133
 
                        return qfalse;
134
 
                *(int *)&((struct sockaddr_in *)sadr)->sin_addr = *(int *)h->h_addr_list[0];
135
 
        }
136
 
        
137
 
        return qtrue;
138
 
}
139
 
 
140
 
/*
141
 
=============
142
 
Sys_StringToAdr
143
 
 
144
 
localhost
145
 
idnewt
146
 
idnewt:28000
147
 
192.246.40.70
148
 
192.246.40.70:28000
149
 
=============
150
 
*/
151
 
qboolean        Sys_StringToAdr (const char *s, netadr_t *a)
152
 
{
153
 
        struct sockaddr_in sadr;
154
 
        
155
 
        if (!Sys_StringToSockaddr (s, (struct sockaddr *)&sadr))
156
 
                return qfalse;
157
 
        
158
 
        SockadrToNetadr (&sadr, a);
159
 
 
160
 
        return qtrue;
161
 
}
162
 
 
163
 
 
164
 
//=============================================================================
165
 
 
166
 
qboolean        Sys_GetPacket (netadr_t *net_from, msg_t *net_message)
167
 
{
168
 
        int     ret;
169
 
        struct sockaddr_in      from;
170
 
        socklen_t       fromlen;
171
 
        int             net_socket;
172
 
        int             protocol;
173
 
        int             err;
174
 
 
175
 
        for (protocol = 0 ; protocol < 2 ; protocol++)
176
 
        {
177
 
                if (protocol == 0)
178
 
                        net_socket = ip_socket;
179
 
                else
180
 
                        net_socket = ipx_socket;
181
 
 
182
 
                if (!net_socket)
183
 
                        continue;
184
 
 
185
 
                fromlen = sizeof(from);
186
 
                ret = recvfrom (net_socket, net_message->data, net_message->maxsize
187
 
                        , 0, (struct sockaddr *)&from, &fromlen);
188
 
 
189
 
                SockadrToNetadr (&from, net_from);
190
 
                // bk000305: was missing
191
 
                net_message->readcount = 0;
192
 
 
193
 
                if (ret == -1)
194
 
                {
195
 
                        err = errno;
196
 
 
197
 
                        if (err == EWOULDBLOCK || err == ECONNREFUSED)
198
 
                                continue;
199
 
                        Com_Printf ("NET_GetPacket: %s from %s\n", NET_ErrorString(),
200
 
                                                NET_AdrToString(*net_from));
201
 
                        continue;
202
 
                }
203
 
 
204
 
                if (ret == net_message->maxsize)
205
 
                {
206
 
                        Com_Printf ("Oversize packet from %s\n", NET_AdrToString (*net_from));
207
 
                        continue;
208
 
                }
209
 
 
210
 
                net_message->cursize = ret;
211
 
                return qtrue;
212
 
        }
213
 
 
214
 
        return qfalse;
215
 
}
216
 
 
217
 
//=============================================================================
218
 
 
219
 
void    Sys_SendPacket( int length, const void *data, netadr_t to )
220
 
{
221
 
        int             ret;
222
 
        struct sockaddr_in      addr;
223
 
        int             net_socket;
224
 
 
225
 
        if (to.type == NA_BROADCAST)
226
 
        {
227
 
                net_socket = ip_socket;
228
 
        }
229
 
        else if (to.type == NA_IP)
230
 
        {
231
 
                net_socket = ip_socket;
232
 
        }
233
 
        else if (to.type == NA_IPX)
234
 
        {
235
 
                net_socket = ipx_socket;
236
 
        }
237
 
        else if (to.type == NA_BROADCAST_IPX)
238
 
        {
239
 
                net_socket = ipx_socket;
240
 
        }
241
 
        else {
242
 
                Com_Error (ERR_FATAL, "NET_SendPacket: bad address type");
243
 
                return;
244
 
        }
245
 
 
246
 
        if (!net_socket)
247
 
                return;
248
 
 
249
 
        NetadrToSockadr (&to, &addr);
250
 
 
251
 
        ret = sendto (net_socket, data, length, 0, (struct sockaddr *)&addr, sizeof(addr) );
252
 
        if (ret == -1)
253
 
        {
254
 
                Com_Printf ("NET_SendPacket ERROR: %s to %s\n", NET_ErrorString(),
255
 
                                NET_AdrToString (to));
256
 
        }
257
 
}
258
 
 
259
 
 
260
 
//=============================================================================
261
 
 
262
 
/*
263
 
==================
264
 
Sys_IsLANAddress
265
 
 
266
 
LAN clients will have their rate var ignored
267
 
==================
268
 
*/
269
 
qboolean        Sys_IsLANAddress (netadr_t adr) {
270
 
        int             i;
271
 
 
272
 
        if( adr.type == NA_LOOPBACK ) {
273
 
                return qtrue;
274
 
        }
275
 
 
276
 
        if( adr.type == NA_IPX ) {
277
 
                return qtrue;
278
 
        }
279
 
 
280
 
        if( adr.type != NA_IP ) {
281
 
                return qfalse;
282
 
        }
283
 
 
284
 
        // RFC1918:
285
 
        // 10.0.0.0        -   10.255.255.255  (10/8 prefix)
286
 
        // 172.16.0.0      -   172.31.255.255  (172.16/12 prefix)
287
 
        // 192.168.0.0     -   192.168.255.255 (192.168/16 prefix)
288
 
        if(adr.ip[0] == 10)
289
 
                return qtrue;
290
 
        if(adr.ip[0] == 172 && (adr.ip[1]&0xf0) == 16)
291
 
                return qtrue;
292
 
        if(adr.ip[0] == 192 && adr.ip[1] == 168)
293
 
                return qtrue;
294
 
 
295
 
        // the checks below are bogus, aren't they? -- ln
296
 
 
297
 
        // choose which comparison to use based on the class of the address being tested
298
 
        // any local adresses of a different class than the address being tested will fail based on the first byte
299
 
 
300
 
        // Class A
301
 
        if( (adr.ip[0] & 0x80) == 0x00 ) {
302
 
                for ( i = 0 ; i < numIP ; i++ ) {
303
 
                        if( adr.ip[0] == localIP[i][0] ) {
304
 
                                return qtrue;
305
 
                        }
306
 
                }
307
 
                // the RFC1918 class a block will pass the above test
308
 
                return qfalse;
309
 
        }
310
 
 
311
 
        // Class B
312
 
        if( (adr.ip[0] & 0xc0) == 0x80 ) {
313
 
                for ( i = 0 ; i < numIP ; i++ ) {
314
 
                        if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] ) {
315
 
                                return qtrue;
316
 
                        }
317
 
                        // also check against the RFC1918 class b blocks
318
 
                        if( adr.ip[0] == 172 && localIP[i][0] == 172 && (adr.ip[1] & 0xf0) == 16 && (localIP[i][1] & 0xf0) == 16 ) {
319
 
                                return qtrue;
320
 
                        }
321
 
                }
322
 
                return qfalse;
323
 
        }
324
 
 
325
 
        // Class C
326
 
        for ( i = 0 ; i < numIP ; i++ ) {
327
 
                if( adr.ip[0] == localIP[i][0] && adr.ip[1] == localIP[i][1] && adr.ip[2] == localIP[i][2] ) {
328
 
                        return qtrue;
329
 
                }
330
 
                // also check against the RFC1918 class c blocks
331
 
                if( adr.ip[0] == 192 && localIP[i][0] == 192 && adr.ip[1] == 168 && localIP[i][1] == 168 ) {
332
 
                        return qtrue;
333
 
                }
334
 
        }
335
 
        return qfalse;
336
 
}
337
 
 
338
 
/*
339
 
==================
340
 
Sys_ShowIP
341
 
==================
342
 
*/
343
 
void Sys_ShowIP(void) {
344
 
        int i;
345
 
 
346
 
        for (i = 0; i < numIP; i++) {
347
 
                Com_Printf( "IP: %i.%i.%i.%i\n", localIP[i][0], localIP[i][1], localIP[i][2], localIP[i][3] );
348
 
        }
349
 
}
350
 
 
351
 
/*
352
 
=====================
353
 
NET_GetLocalAddress
354
 
=====================
355
 
*/
356
 
#ifdef MACOS_X
357
 
// Don't do a forward mapping from the hostname of the machine to the IP.
358
 
// The reason is that we might have obtained an IP address from DHCP and
359
 
// there might not be any name registered for the machine.  On Mac OS X,
360
 
// the machine name defaults to 'localhost' and NetInfo has 127.0.0.1
361
 
// listed for this name.  Instead, we want to get a list of all the IP
362
 
// network interfaces on the machine. This code adapted from
363
 
// OmniNetworking.
364
 
 
365
 
 
366
 
#ifdef _SIZEOF_ADDR_IFREQ
367
 
        // tjw: OSX 10.4 does not have sa_len
368
 
        #define IFR_NEXT(ifr)   \
369
 
        ((struct ifreq *) ((char *) ifr + _SIZEOF_ADDR_IFREQ(*ifr)))
370
 
#else
371
 
        // tjw: assume that once upon a time some version did have sa_len
372
 
        #define IFR_NEXT(ifr)   \
373
 
        ((struct ifreq *) ((char *) (ifr) + sizeof(*(ifr)) + \
374
 
        MAX(0, (int) (ifr)->ifr_addr.sa_len - (int) sizeof((ifr)->ifr_addr))))
375
 
#endif
376
 
 
377
 
void NET_GetLocalAddress( void ) {
378
 
        struct ifreq requestBuffer[MAX_IPS], *linkInterface, *inetInterface;
379
 
        struct ifconf ifc;
380
 
        struct ifreq ifr;
381
 
        struct sockaddr_dl *sdl;
382
 
        int interfaceSocket;
383
 
        int family;
384
 
        
385
 
        Com_Printf("NET_GetLocalAddress: Querying for network interfaces\n");
386
 
        
387
 
        // Set this early so we can just return if there is an error
388
 
        numIP = 0;
389
 
        
390
 
        ifc.ifc_len = sizeof(requestBuffer);
391
 
        ifc.ifc_buf = (caddr_t)requestBuffer;
392
 
 
393
 
        // Since we get at this info via an ioctl, we need a temporary little socket.
394
 
        // This will only get AF_INET interfaces, but we probably don't care about
395
 
        // anything else.  If we do end up caring later, we should add a
396
 
        // ONAddressFamily and at a -interfaces method to it.
397
 
        family = AF_INET;
398
 
        if ((interfaceSocket = socket(family, SOCK_DGRAM, 0)) < 0) {
399
 
            Com_Printf("NET_GetLocalAddress: Unable to create temporary socket, errno = %d\n", errno);
400
 
            return;
401
 
        }
402
 
 
403
 
        if (ioctl(interfaceSocket, SIOCGIFCONF, &ifc) != 0) {
404
 
            Com_Printf("NET_GetLocalAddress: Unable to get list of network interfaces, errno = %d\n", errno);
405
 
            return;
406
 
        }
407
 
 
408
 
 
409
 
        linkInterface = (struct ifreq *) ifc.ifc_buf;
410
 
        while ((char *) linkInterface < &ifc.ifc_buf[ifc.ifc_len]) {
411
 
            unsigned int nameLength;
412
 
 
413
 
            // The ioctl returns both the entries having the address (AF_INET)
414
 
            // and the link layer entries (AF_LINK).  The AF_LINK entry has the
415
 
            // link layer address which contains the interface type.  This is the
416
 
            // only way I can see to get this information.  We cannot assume that
417
 
            // we will get bot an AF_LINK and AF_INET entry since the interface
418
 
            // may not be configured.  For example, if you have a 10Mb port on
419
 
            // the motherboard and a 100Mb card, you may not configure the
420
 
            // motherboard port.
421
 
 
422
 
            // For each AF_LINK entry...
423
 
            if (linkInterface->ifr_addr.sa_family == AF_LINK) {
424
 
                // if there is a matching AF_INET entry
425
 
                inetInterface = (struct ifreq *) ifc.ifc_buf;
426
 
                while ((char *) inetInterface < &ifc.ifc_buf[ifc.ifc_len]) {
427
 
                    if (inetInterface->ifr_addr.sa_family == AF_INET &&
428
 
                        !strncmp(inetInterface->ifr_name, linkInterface->ifr_name,
429
 
                          sizeof(linkInterface->ifr_name))) {
430
 
 
431
 
                        for (nameLength = 0; nameLength < IFNAMSIZ; nameLength++)
432
 
                            if (!linkInterface->ifr_name[nameLength])
433
 
                                break;
434
 
 
435
 
                        sdl = (struct sockaddr_dl *)&linkInterface->ifr_addr;
436
 
                        // Skip loopback interfaces
437
 
                        if (sdl->sdl_type != IFT_LOOP) {
438
 
                            // Get the local interface address
439
 
                            strncpy(ifr.ifr_name, inetInterface->ifr_name, sizeof(ifr.ifr_name));
440
 
                            if (ioctl(interfaceSocket, OSIOCGIFADDR, (caddr_t)&ifr) < 0) {
441
 
                                Com_Printf("NET_GetLocalAddress: Unable to get local address "
442
 
                                    "for interface '%s', errno = %d\n", inetInterface->ifr_name, errno);
443
 
                            } else {
444
 
                                struct sockaddr_in *sin;
445
 
                                int ip;
446
 
            
447
 
                                sin = (struct sockaddr_in *)&ifr.ifr_addr;
448
 
            
449
 
                                ip = ntohl(sin->sin_addr.s_addr);
450
 
                                localIP[ numIP ][0] = (ip >> 24) & 0xff;
451
 
                                localIP[ numIP ][1] = (ip >> 16) & 0xff;
452
 
                                localIP[ numIP ][2] = (ip >>  8) & 0xff;
453
 
                                localIP[ numIP ][3] = (ip >>  0) & 0xff;
454
 
                                Com_Printf( "IP: %i.%i.%i.%i (%s)\n",
455
 
                                    localIP[ numIP ][0], localIP[ numIP ][1],
456
 
                                    localIP[ numIP ][2], localIP[ numIP ][3],
457
 
                                    inetInterface->ifr_name);
458
 
                                numIP++;
459
 
                            }
460
 
                        }
461
 
 
462
 
                        // We will assume that there is only one AF_INET entry per AF_LINK entry.
463
 
                        // What happens when we have an interface that has multiple IP addresses, or
464
 
                        // can that even happen?
465
 
                        // break;
466
 
                    }
467
 
                    inetInterface = IFR_NEXT(inetInterface);
468
 
                }
469
 
            }
470
 
            linkInterface = IFR_NEXT(linkInterface);
471
 
        }
472
 
        Com_Printf("NET_GetLocalAddress: DONE querying for network interfaces\n");
473
 
 
474
 
        close(interfaceSocket);
475
 
}
476
 
 
477
 
#else
478
 
void NET_GetLocalAddress( void ) {
479
 
        char                            hostname[256];
480
 
        struct hostent          *hostInfo;
481
 
        // int                                  error; // bk001204 - unused
482
 
        char                            *p;
483
 
        int                                     ip;
484
 
        int                                     n;
485
 
 
486
 
        if ( gethostname( hostname, 256 ) == -1 ) {
487
 
                return;
488
 
        }
489
 
 
490
 
        hostInfo = gethostbyname( hostname );
491
 
        if ( !hostInfo ) {
492
 
                return;
493
 
        }
494
 
 
495
 
        Com_Printf( "Hostname: %s\n", hostInfo->h_name );
496
 
        n = 0;
497
 
        while( ( p = hostInfo->h_aliases[n++] ) != NULL ) {
498
 
                Com_Printf( "Alias: %s\n", p );
499
 
        }
500
 
 
501
 
        if ( hostInfo->h_addrtype != AF_INET ) {
502
 
                return;
503
 
        }
504
 
 
505
 
        numIP = 0;
506
 
        while( ( p = hostInfo->h_addr_list[numIP++] ) != NULL && numIP < MAX_IPS ) {
507
 
                ip = ntohl( *(int *)p );
508
 
                localIP[ numIP ][0] = p[0];
509
 
                localIP[ numIP ][1] = p[1];
510
 
                localIP[ numIP ][2] = p[2];
511
 
                localIP[ numIP ][3] = p[3];
512
 
                Com_Printf( "IP: %i.%i.%i.%i\n", ( ip >> 24 ) & 0xff, ( ip >> 16 ) & 0xff, ( ip >> 8 ) & 0xff, ip & 0xff );
513
 
        }
514
 
}
515
 
#endif
516
 
 
517
 
/*
518
 
====================
519
 
NET_OpenIP
520
 
====================
521
 
*/
522
 
// bk001204 - prototype needed
523
 
int NET_IPSocket (char *net_interface, int port);
524
 
void NET_OpenIP (void)
525
 
{
526
 
        cvar_t  *ip;
527
 
        int             port;
528
 
        int             i;
529
 
 
530
 
        ip = Cvar_Get ("net_ip", "localhost", 0);
531
 
 
532
 
        port = Cvar_Get("net_port", va("%i", PORT_SERVER), 0)->value;
533
 
 
534
 
        for ( i = 0 ; i < 10 ; i++ ) {
535
 
                ip_socket = NET_IPSocket (ip->string, port + i);
536
 
                if ( ip_socket ) {
537
 
                        Cvar_SetValue( "net_port", port + i );
538
 
                        NET_GetLocalAddress();
539
 
                        return;
540
 
                }
541
 
        }
542
 
        Com_Error (ERR_FATAL, "Couldn't allocate IP port");
543
 
}
544
 
 
545
 
 
546
 
/*
547
 
====================
548
 
NET_Init
549
 
====================
550
 
*/
551
 
void NET_Init (void)
552
 
{
553
 
        noudp = Cvar_Get ("net_noudp", "0", 0);
554
 
        // open sockets
555
 
        if (! noudp->value) {
556
 
                NET_OpenIP ();
557
 
        }
558
 
}
559
 
 
560
 
 
561
 
/*
562
 
====================
563
 
NET_IPSocket
564
 
====================
565
 
*/
566
 
int NET_IPSocket (char *net_interface, int port)
567
 
{
568
 
        int newsocket;
569
 
        struct sockaddr_in address;
570
 
        qboolean _qtrue = qtrue;
571
 
        int     i = 1;
572
 
 
573
 
        if ( net_interface ) {
574
 
                Com_Printf("Opening IP socket: %s:%i\n", net_interface, port );
575
 
        } else {
576
 
                Com_Printf("Opening IP socket: localhost:%i\n", port );
577
 
        }
578
 
 
579
 
        if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
580
 
        {
581
 
                Com_Printf ("ERROR: UDP_OpenSocket: socket: %s", NET_ErrorString());
582
 
                return 0;
583
 
        }
584
 
 
585
 
        // make it non-blocking
586
 
        if (ioctl (newsocket, FIONBIO, &_qtrue) == -1)
587
 
        {
588
 
                Com_Printf ("ERROR: UDP_OpenSocket: ioctl FIONBIO:%s\n", NET_ErrorString());
589
 
                return 0;
590
 
        }
591
 
 
592
 
        // make it broadcast capable
593
 
        if (setsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) == -1)
594
 
        {
595
 
                Com_Printf ("ERROR: UDP_OpenSocket: setsockopt SO_BROADCAST:%s\n", NET_ErrorString());
596
 
                return 0;
597
 
        }
598
 
 
599
 
        if (!net_interface || !net_interface[0] || !Q_stricmp(net_interface, "localhost"))
600
 
                address.sin_addr.s_addr = INADDR_ANY;
601
 
        else
602
 
                Sys_StringToSockaddr (net_interface, (struct sockaddr *)&address);
603
 
 
604
 
        if (port == PORT_ANY)
605
 
                address.sin_port = 0;
606
 
        else
607
 
                address.sin_port = htons((short)port);
608
 
 
609
 
        address.sin_family = AF_INET;
610
 
 
611
 
        if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
612
 
        {
613
 
                Com_Printf ("ERROR: UDP_OpenSocket: bind: %s\n", NET_ErrorString());
614
 
                close (newsocket);
615
 
                return 0;
616
 
        }
617
 
 
618
 
        return newsocket;
619
 
}
620
 
 
621
 
/*
622
 
====================
623
 
NET_Shutdown
624
 
====================
625
 
*/
626
 
void    NET_Shutdown (void)
627
 
{
628
 
        if (ip_socket) {
629
 
                close(ip_socket);
630
 
                ip_socket = 0;
631
 
        }
632
 
}
633
 
 
634
 
 
635
 
/*
636
 
====================
637
 
NET_ErrorString
638
 
====================
639
 
*/
640
 
char *NET_ErrorString (void)
641
 
{
642
 
        int             code;
643
 
 
644
 
        code = errno;
645
 
        return strerror (code);
646
 
}
647
 
 
648
 
// sleeps msec or until net socket is ready
649
 
void NET_Sleep(int msec)
650
 
{
651
 
        struct timeval timeout;
652
 
        fd_set  fdset;
653
 
        extern qboolean stdin_active;
654
 
        int highestfd = 0;
655
 
 
656
 
        if (!com_dedicated->integer)
657
 
                return; // we're not a server, just run full speed
658
 
 
659
 
        FD_ZERO(&fdset);
660
 
        if (stdin_active)
661
 
        {
662
 
                FD_SET(0, &fdset); // stdin is processed too
663
 
                highestfd = 1;
664
 
        }
665
 
        if(ip_socket)
666
 
        {
667
 
                FD_SET(ip_socket, &fdset); // network socket
668
 
                if(ip_socket >= highestfd)
669
 
                        highestfd = ip_socket + 1;
670
 
        }
671
 
        
672
 
        if(highestfd)
673
 
        {
674
 
                if(msec >= 0)
675
 
                {
676
 
                        timeout.tv_sec = msec/1000;
677
 
                        timeout.tv_usec = (msec%1000)*1000;
678
 
                        select(highestfd, &fdset, NULL, NULL, &timeout);
679
 
                }
680
 
                else
681
 
                {
682
 
                        // Block indefinitely
683
 
                        select(highestfd, &fdset, NULL, NULL, NULL);
684
 
                }
685
 
        }
686
 
}
687