1cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich/*
2cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichCopyright (C) 1996-1997 Id Software, Inc.
3cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
4cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichThis program is free software; you can redistribute it and/or
5cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichmodify it under the terms of the GNU General Public License
6cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichas published by the Free Software Foundation; either version 2
7cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichof the License, or (at your option) any later version.
8cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
9cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichThis program is distributed in the hope that it will be useful,
10cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichbut WITHOUT ANY WARRANTY; without even the implied warranty of
11cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
13cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichSee the GNU General Public License for more details.
14cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
15cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichYou should have received a copy of the GNU General Public License
16cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichalong with this program; if not, write to the Free Software
17cabb5dd768714a7df34469a096b5e1aa815a2c22Jack PalevichFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
19cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich*/
209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream// net_udp.c
219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "quakedef.h"
239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <sys/types.h>
259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <sys/socket.h>
269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <netinet/in.h>
279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <netdb.h>
289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <sys/param.h>
299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <sys/ioctl.h>
309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <errno.h>
31cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#include <unistd.h>
32cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
33cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#include <arpa/inet.h>
349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#ifdef __sun__
369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <sys/filio.h>
379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#endif
389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#ifdef NeXT
409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include <libc.h>
419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#endif
429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamextern cvar_t hostname;
449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int net_acceptsocket = -1;		// socket for fielding new connections
469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int net_controlsocket;
479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic int net_broadcastsocket = 0;
489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic struct qsockaddr broadcastaddr;
499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamstatic unsigned long myAddr;
519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream#include "net_udp.h"
539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
54cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// **** Start of Android-specific code ****
55cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// copied from ifc_utils.c
56cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich//
57cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// This isn't a good long-term solution:
58cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// 1) It is hard-wired to a particular wireless driver
59cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// 2) It doesn't handle the IP address changing over time
60cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
61cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#include <sys/ioctl.h>
62cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#include <net/if.h>
63cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
64cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichstatic int ifc_ctl_sock = -1;
65cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
66cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint ifc_init(void)
67cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
68cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    if (ifc_ctl_sock == -1) {
69cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0);
70cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        if (ifc_ctl_sock < 0) {
71cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        	Con_Printf("socket() failed: %s\n", strerror(errno));
72cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        }
73cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    }
74cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    return ifc_ctl_sock < 0 ? -1 : 0;
75cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
76cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
77cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid ifc_close(void)
78cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
79cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    if (ifc_ctl_sock != -1) {
80cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        (void)close(ifc_ctl_sock);
81cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        ifc_ctl_sock = -1;
82cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    }
83cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
84cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
85cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichstatic void ifc_init_ifr(const char *name, struct ifreq *ifr)
86cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
87cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    memset(ifr, 0, sizeof(struct ifreq));
88cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    strncpy(ifr->ifr_name, name, IFNAMSIZ);
89cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    ifr->ifr_name[IFNAMSIZ - 1] = 0;
90cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
91cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
92cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint ifc_get_info(const char *name, in_addr_t *addr, in_addr_t *mask, unsigned *flags)
93cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich{
94cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    struct ifreq ifr;
95cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    ifc_init_ifr(name, &ifr);
96cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
97cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    if (addr != NULL) {
98cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        if(ioctl(ifc_ctl_sock, SIOCGIFADDR, &ifr) < 0) {
99cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich            *addr = 0;
100cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        } else {
101cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich            *addr = ((struct sockaddr_in*) (void*) &ifr.ifr_addr)->sin_addr.s_addr;
102cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        }
103cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    }
104cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
105cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    if (mask != NULL) {
106cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        if(ioctl(ifc_ctl_sock, SIOCGIFNETMASK, &ifr) < 0) {
107cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich            *mask = 0;
108cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        } else {
109cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich            *mask = ((struct sockaddr_in*) (void*) &ifr.ifr_addr)->sin_addr.s_addr;
110cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        }
111cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    }
112cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
113cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    if (flags != NULL) {
114cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        if(ioctl(ifc_ctl_sock, SIOCGIFFLAGS, &ifr) < 0) {
115cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich            *flags = 0;
116cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        } else {
117cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich            *flags = ifr.ifr_flags;
118cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich        }
119cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    }
120cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
121cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich    return 0;
122cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
123cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
124cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichvoid AndroidGetAddr() {
125cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (ifc_init()) {
126cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return;
127cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
128cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	in_addr_t addr;
129cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	ifc_get_info("tiwlan0", &addr, 0, 0);
130cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	myAddr = addr;
131cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	ifc_close();
132cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich}
133cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
134cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
135cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich// **** End of Android-specific code ****
136cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
1379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
1389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_Init (void)
1409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
1419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	struct hostent *local;
1429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char	buff[MAXHOSTNAMELEN];
1439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	struct qsockaddr addr;
1449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char *colon;
145cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
1469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (COM_CheckParm ("-noudp"))
1479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
1489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
149cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#if 1 // Android
150cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	AndroidGetAddr();
151cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#else
1529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// determine my name & address
1539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	gethostname(buff, MAXHOSTNAMELEN);
1549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	local = gethostbyname(buff);
155cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
156cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if(!local)
157cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	{
158cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		Con_Printf("Could not gethostbyname(\"%s\")\n", buff);
159cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich		return -1;
160cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	}
161cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
1629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	myAddr = *(int *)local->h_addr_list[0];
1639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// if the quake hostname isn't set, set it to the machine name
1659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (Q_strcmp(hostname.string, "UNNAMED") == 0)
1669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
1679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		buff[15] = 0;
1689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Cvar_Set ("hostname", buff);
1699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
170cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich#endif
1719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if ((net_controlsocket = UDP_OpenSocket (0)) == -1)
1729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Sys_Error("UDP_Init: Unable to open control socket\n");
1739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
174cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	sockaddr_in temp;
175cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
176cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	memcpy(&temp, &broadcastaddr, sizeof(temp));
177cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
178cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	temp.sin_family = AF_INET;
179cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	temp.sin_addr.s_addr = INADDR_BROADCAST;
180cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	temp.sin_port = htons(net_hostport);
181cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
182cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	memcpy(&broadcastaddr, &temp, sizeof(temp));
1839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	UDP_GetSocketAddr (net_controlsocket, &addr);
1859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_strcpy(my_tcpip_address,  UDP_AddrToString (&addr));
1869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	colon = Q_strrchr (my_tcpip_address, ':');
1879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (colon)
1889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		*colon = 0;
1899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Con_Printf("UDP Initialized\n");
1919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	tcpipAvailable = true;
1929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return net_controlsocket;
1949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
1959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
1979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
1989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid UDP_Shutdown (void)
1999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	UDP_Listen (false);
2019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	UDP_CloseSocket (net_controlsocket);
2029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
2039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
2059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamvoid UDP_Listen (qboolean state)
2079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// enable listening
2099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (state)
2109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
2119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (net_acceptsocket != -1)
2129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return;
2139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if ((net_acceptsocket = UDP_OpenSocket (net_hostport)) == -1)
2149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			Sys_Error ("UDP_Listen: Unable to open accept socket\n");
2159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
2169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
2179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// disable listening
2199fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (net_acceptsocket == -1)
2209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return;
2219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	UDP_CloseSocket (net_acceptsocket);
2229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	net_acceptsocket = -1;
2239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
2249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
2269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_OpenSocket (int port)
2289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int newsocket;
230cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	union {
231cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	    struct sockaddr_in in;
232cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	    struct sockaddr sockaddr;
233cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	} address;
2349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	qboolean _true = true;
2359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
2379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
2389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (ioctl (newsocket, FIONBIO, (char *)&_true) == -1)
2409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		goto ErrorReturn;
2419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
242cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	address.in.sin_family = AF_INET;
243cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	address.in.sin_addr.s_addr = INADDR_ANY;
244cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	address.in.sin_port = htons(port);
245cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if( bind (newsocket, &address.sockaddr, sizeof(address.in)) == -1)
2469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		goto ErrorReturn;
2479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return newsocket;
2499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamErrorReturn:
2519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	close (newsocket);
2529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return -1;
2539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
2549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
2569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_CloseSocket (int socket)
2589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (socket == net_broadcastsocket)
2609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		net_broadcastsocket = 0;
2619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return close (socket);
2629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
2639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
2669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream/*
2679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream============
2689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamPartialIPAddress
2699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamthis lets you type only as much of the net address as required, using
2719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamthe local network components to fill in the rest
2729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream============
2739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream*/
274cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichstatic int PartialIPAddress (const char *in, struct qsockaddr *hostaddr)
2759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
2769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char buff[256];
2779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	char *b;
2789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int addr;
2799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int num;
2809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int mask;
2819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int run;
2829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int port;
283cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
2849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	buff[0] = '.';
2859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	b = buff;
2869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	strcpy(buff+1, in);
2879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (buff[1] == '.')
2889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		b++;
2899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
2909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	addr = 0;
2919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	mask=-1;
2929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	while (*b == '.')
2939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
2949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		b++;
2959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		num = 0;
2969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		run = 0;
2979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		while (!( *b < '0' || *b > '9'))
2989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
2999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		  num = num*10 + *b++ - '0';
3009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		  if (++run > 3)
3019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		  	return -1;
3029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
3039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0)
3049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return -1;
3059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (num < 0 || num > 255)
3069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return -1;
3079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		mask<<=8;
3089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		addr = (addr<<8) + num;
3099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
310cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
3119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (*b++ == ':')
3129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		port = Q_atoi(b);
3139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	else
3149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		port = net_hostport;
3159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	hostaddr->sa_family = AF_INET;
317cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port);
3189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr);
319cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
3209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
3219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_Connect (int socket, struct qsockaddr *addr)
3259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
3279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_CheckNewConnections (void)
3329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	unsigned long	available;
3349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (net_acceptsocket == -1)
3369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
3379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (ioctl (net_acceptsocket, FIONREAD, &available) == -1)
3399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Sys_Error ("UDP: ioctlsocket (FIONREAD) failed\n");
3409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (available)
3419fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return net_acceptsocket;
3429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return -1;
3439fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr)
3489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int addrlen = sizeof (struct qsockaddr);
3509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int ret;
3519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
352cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, (socklen_t*) &addrlen);
3539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED))
3549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return 0;
3559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return ret;
3569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_MakeSocketBroadcastCapable (int socket)
3619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int				i = 1;
3639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	// make this socket broadcast capable
3659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0)
3669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
3679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	net_broadcastsocket = socket;
3689fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
3709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3749fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_Broadcast (int socket, byte *buf, int len)
3759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int ret;
3779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (socket != net_broadcastsocket)
3799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
3809fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (net_broadcastsocket != 0)
3819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			Sys_Error("Attempted to use multiple broadcasts sockets\n");
3829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		ret = UDP_MakeSocketBroadcastCapable (socket);
3839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		if (ret == -1)
3849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		{
3859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			Con_Printf("Unable to make socket broadcast capable\n");
3869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream			return ret;
3879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		}
3889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
3899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return UDP_Write (socket, buf, len, &broadcastaddr);
3919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
3929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
3949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr)
3969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
3979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int ret;
3989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
3999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr));
4009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (ret == -1 && errno == EWOULDBLOCK)
4019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return 0;
4029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return ret;
4039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamchar *UDP_AddrToString (struct qsockaddr *addr)
4089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
4099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	static char buffer[22];
4109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int haddr;
4119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
4139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	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));
4149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return buffer;
4159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4179fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4189fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
419cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint UDP_StringToAddr (const char *string, struct qsockaddr *addr)
4209fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
4219fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int ha1, ha2, ha3, ha4, hp;
4229fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int ipaddr;
4239fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4249fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
4259fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
4269fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4279fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	addr->sa_family = AF_INET;
4289fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
4299fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)addr)->sin_port = htons(hp);
4309fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
4319fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4329fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4339fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4349fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4359fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_GetSocketAddr (int socket, struct qsockaddr *addr)
4369fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
4379fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	int addrlen = sizeof(struct qsockaddr);
4389fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	unsigned int a;
4399fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4409fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_memset(addr, 0, sizeof(struct qsockaddr));
441cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	getsockname(socket, (struct sockaddr *)addr, (socklen_t*) &addrlen);
4429fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	a = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
443cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	if (a == 0 || (in_addr_t) a == inet_addr("127.0.0.1"))
4449fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr;
4459fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4469fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
4479fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4489fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4499fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4509fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4519fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_GetNameFromAddr (struct qsockaddr *addr, char *name)
4529fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
4539fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	struct hostent *hostentry;
4549fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4559fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET);
4569fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (hostentry)
4579fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	{
4589fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1);
4599fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return 0;
4609fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	}
4619fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4629fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	Q_strcpy (name, UDP_AddrToString (addr));
4639fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
4649fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4659fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4669fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4679fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
468cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevichint UDP_GetAddrFromName(const char *name, struct qsockaddr *addr)
4699fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
4709fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	struct hostent *hostentry;
4719fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4729fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (name[0] >= '0' && name[0] <= '9')
4739fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return PartialIPAddress (name, addr);
474cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich
4759fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	hostentry = gethostbyname (name);
4769fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (!hostentry)
4779fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
4789fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4799fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	addr->sa_family = AF_INET;
480cabb5dd768714a7df34469a096b5e1aa815a2c22Jack Palevich	((struct sockaddr_in *)addr)->sin_port = htons(net_hostport);
4819fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
4829fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4839fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
4849fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
4859fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4869fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
4879fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4889fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
4899fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
4909fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (addr1->sa_family != addr2->sa_family)
4919fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
4929fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4939fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
4949fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return -1;
4959fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4969fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
4979fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream		return 1;
4989fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
4999fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
5009fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
5019fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5029fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
5039fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5049fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_GetSocketPort (struct qsockaddr *addr)
5059fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
5069fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return ntohs(((struct sockaddr_in *)addr)->sin_port);
5079fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
5089fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5099fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5109fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstreamint UDP_SetSocketPort (struct qsockaddr *addr, int port)
5119fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream{
5129fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	((struct sockaddr_in *)addr)->sin_port = htons(port);
5139fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream	return 0;
5149fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream}
5159fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream
5169fd67c44777b350dc56f3e70c88963b0d966ffc7quake upstream//=============================================================================
517