|
|
1.1 ! root 1: // net_mpath.c ! 2: ! 3: #include <dpmi.h> ! 4: #include "quakedef.h" ! 5: #include "mpdosock.h" ! 6: ! 7: short flat_selector; ! 8: ! 9: int WSAGetLastError(void); ! 10: void sockets_flush(void); ! 11: ! 12: extern cvar_t hostname; ! 13: ! 14: #define DEFAULTnet_hostport 26000 ! 15: ! 16: #define MAXHOSTNAMELEN 256 ! 17: ! 18: static int net_acceptsocket = -1; // socket for fielding new connections ! 19: static int net_controlsocket; ! 20: static int net_hostport; // udp port number for acceptsocket ! 21: static int net_broadcastsocket = 0; ! 22: //static qboolean ifbcastinit = false; ! 23: static struct qsockaddr broadcastaddr; ! 24: ! 25: static unsigned long myAddr; ! 26: ! 27: #include "net_mp.h" ! 28: ! 29: ! 30: //============================================================================= ! 31: ! 32: int MPATH_Init (void) ! 33: { ! 34: int i; ! 35: struct hostent *local; ! 36: char buff[MAXHOSTNAMELEN]; ! 37: struct qsockaddr addr; ! 38: char *p; ! 39: ! 40: if (COM_CheckParm ("-mpath") == 0) ! 41: return -1; ! 42: ! 43: i = COM_CheckParm ("-udpport"); ! 44: if (i == 0) ! 45: net_hostport = DEFAULTnet_hostport; ! 46: else if (i < com_argc-1) ! 47: net_hostport = Q_atoi (com_argv[i+1]); ! 48: else ! 49: Sys_Error ("MPATH_Init: you must specify a number after -udpport"); ! 50: ! 51: flat_selector = __dpmi_allocate_ldt_descriptors(1); ! 52: if (flat_selector == -1) { ! 53: Con_Printf("MPATH_Init: Can't get flat selector\n"); ! 54: return -1; ! 55: } ! 56: if (__dpmi_set_segment_base_address(flat_selector, 0) == -1) { ! 57: Con_Printf("MPATH_Init: Can't seg flat base!\n"); ! 58: return -1; ! 59: } ! 60: if (__dpmi_set_segment_limit(flat_selector, 0xffffffff) == -1) { ! 61: Con_Printf("MPATH_Init: Can't set segment limit\n"); ! 62: return -1; ! 63: } ! 64: // determine my name & address ! 65: gethostname(buff, MAXHOSTNAMELEN); ! 66: local = gethostbyname(buff); ! 67: myAddr = *(int *)local->h_addr_list[0]; ! 68: ! 69: // if the quake hostname isn't set, set it to the machine name ! 70: if (Q_strcmp(hostname.string, "UNNAMED") == 0) ! 71: { ! 72: // see if it's a text IP address (well, close enough) ! 73: for (p = buff; *p; p++) ! 74: if ((*p < '0' || *p > '9') && *p != '.') ! 75: break; ! 76: ! 77: // if it is a real name, strip off the domain; we only want the host ! 78: if (*p) ! 79: { ! 80: for (i = 0; i < 15; i++) ! 81: if (buff[i] == '.') ! 82: break; ! 83: buff[i] = 0; ! 84: } ! 85: Cvar_Set ("hostname", buff); ! 86: } ! 87: ! 88: if ((net_controlsocket = MPATH_OpenSocket (0)) == -1) ! 89: Sys_Error("MPATH_Init: Unable to open control socket\n"); ! 90: ! 91: ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET; ! 92: ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST; ! 93: ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons(net_hostport); ! 94: ! 95: MPATH_GetSocketAddr (net_controlsocket, &addr); ! 96: Q_strcpy(my_tcpip_address, MPATH_AddrToString (&addr)); ! 97: p = Q_strrchr (my_tcpip_address, ':'); ! 98: if (p) ! 99: *p = 0; ! 100: ! 101: Con_Printf("MPath Initialized\n"); ! 102: tcpipAvailable = true; ! 103: ! 104: return net_controlsocket; ! 105: } ! 106: ! 107: //============================================================================= ! 108: ! 109: void MPATH_Shutdown (void) ! 110: { ! 111: MPATH_Listen (false); ! 112: MPATH_CloseSocket (net_controlsocket); ! 113: } ! 114: ! 115: //============================================================================= ! 116: ! 117: void MPATH_Listen (qboolean state) ! 118: { ! 119: // enable listening ! 120: if (state) ! 121: { ! 122: if (net_acceptsocket != -1) ! 123: return; ! 124: if ((net_acceptsocket = MPATH_OpenSocket (net_hostport)) == -1) ! 125: Sys_Error ("MPATH_Listen: Unable to open accept socket\n"); ! 126: return; ! 127: } ! 128: ! 129: // disable listening ! 130: if (net_acceptsocket == -1) ! 131: return; ! 132: MPATH_CloseSocket (net_acceptsocket); ! 133: net_acceptsocket = -1; ! 134: } ! 135: ! 136: //============================================================================= ! 137: ! 138: int MPATH_OpenSocket (int port) ! 139: { ! 140: int newsocket; ! 141: struct sockaddr_in address; ! 142: u_long _true = 1; ! 143: ! 144: if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) ! 145: return -1; ! 146: ! 147: if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) ! 148: goto ErrorReturn; ! 149: ! 150: address.sin_family = AF_INET; ! 151: address.sin_addr.s_addr = INADDR_ANY; ! 152: address.sin_port = htons(port); ! 153: if( bind (newsocket, (void *)&address, sizeof(address)) == -1) ! 154: goto ErrorReturn; ! 155: ! 156: return newsocket; ! 157: ! 158: ErrorReturn: ! 159: closesocket (newsocket); ! 160: return -1; ! 161: } ! 162: ! 163: //============================================================================= ! 164: ! 165: int MPATH_CloseSocket (int socket) ! 166: { ! 167: if (socket == net_broadcastsocket) ! 168: net_broadcastsocket = 0; ! 169: return closesocket (socket); ! 170: } ! 171: ! 172: ! 173: //============================================================================= ! 174: /* ! 175: ============ ! 176: PartialIPAddress ! 177: ! 178: this lets you type only as much of the net address as required, using ! 179: the local network components to fill in the rest ! 180: ============ ! 181: */ ! 182: static int PartialIPAddress (char *in, struct qsockaddr *hostaddr) ! 183: { ! 184: char buff[256]; ! 185: char *b; ! 186: int addr; ! 187: int num; ! 188: int mask; ! 189: ! 190: buff[0] = '.'; ! 191: b = buff; ! 192: strcpy(buff+1, in); ! 193: if (buff[1] == '.') b++; ! 194: ! 195: addr = 0; ! 196: mask=-1; ! 197: while (*b == '.') ! 198: { ! 199: num = 0; ! 200: if (*++b < '0' || *b > '9') return -1; ! 201: while (!( *b < '0' || *b > '9')) ! 202: num = num*10 + *(b++) - '0'; ! 203: mask<<=8; ! 204: addr = (addr<<8) + num; ! 205: } ! 206: ! 207: hostaddr->sa_family = AF_INET; ! 208: ((struct sockaddr_in *)hostaddr)->sin_port = htons(net_hostport); ! 209: ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr); ! 210: ! 211: return 0; ! 212: } ! 213: //============================================================================= ! 214: ! 215: int MPATH_Connect (int socket, struct qsockaddr *addr) ! 216: { ! 217: return 0; ! 218: } ! 219: ! 220: //============================================================================= ! 221: ! 222: int MPATH_CheckNewConnections (void) ! 223: { ! 224: char buf[4]; ! 225: ! 226: if (net_acceptsocket == -1) ! 227: return -1; ! 228: ! 229: if (recvfrom (net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) > 0) ! 230: return net_acceptsocket; ! 231: return -1; ! 232: } ! 233: ! 234: //============================================================================= ! 235: ! 236: int MPATH_Read (int socket, byte *buf, int len, struct qsockaddr *addr) ! 237: { ! 238: int addrlen = sizeof (struct qsockaddr); ! 239: int ret; ! 240: ! 241: ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, &addrlen); ! 242: if (ret == -1) ! 243: { ! 244: int errno = WSAGetLastError(); ! 245: ! 246: if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED) ! 247: return 0; ! 248: ! 249: } ! 250: return ret; ! 251: } ! 252: ! 253: //============================================================================= ! 254: ! 255: int MPATH_MakeSocketBroadcastCapable (int socket) ! 256: { ! 257: int i = 1; ! 258: ! 259: // make this socket broadcast capable ! 260: if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0) ! 261: return -1; ! 262: net_broadcastsocket = socket; ! 263: ! 264: return 0; ! 265: } ! 266: ! 267: //============================================================================= ! 268: ! 269: int MPATH_Broadcast (int socket, byte *buf, int len) ! 270: { ! 271: int ret; ! 272: ! 273: if (socket != net_broadcastsocket) ! 274: { ! 275: if (net_broadcastsocket != 0) ! 276: Sys_Error("Attempted to use multiple broadcasts sockets\n"); ! 277: ret = MPATH_MakeSocketBroadcastCapable (socket); ! 278: if (ret == -1) ! 279: { ! 280: Con_Printf("Unable to make socket broadcast capable\n"); ! 281: return ret; ! 282: } ! 283: } ! 284: ! 285: return MPATH_Write (socket, buf, len, &broadcastaddr); ! 286: } ! 287: ! 288: //============================================================================= ! 289: ! 290: int MPATH_Write (int socket, byte *buf, int len, struct qsockaddr *addr) ! 291: { ! 292: int ret; ! 293: ! 294: ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr)); ! 295: if (ret == -1) ! 296: if (WSAGetLastError() == WSAEWOULDBLOCK) ! 297: return 0; ! 298: ! 299: sockets_flush(); ! 300: ! 301: return ret; ! 302: } ! 303: ! 304: //============================================================================= ! 305: ! 306: char *MPATH_AddrToString (struct qsockaddr *addr) ! 307: { ! 308: static char buffer[22]; ! 309: int haddr; ! 310: ! 311: haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr); ! 312: 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)); ! 313: return buffer; ! 314: } ! 315: ! 316: //============================================================================= ! 317: ! 318: int MPATH_StringToAddr (char *string, struct qsockaddr *addr) ! 319: { ! 320: int ha1, ha2, ha3, ha4, hp; ! 321: int ipaddr; ! 322: ! 323: sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp); ! 324: ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; ! 325: ! 326: addr->sa_family = AF_INET; ! 327: ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr); ! 328: ((struct sockaddr_in *)addr)->sin_port = htons(hp); ! 329: return 0; ! 330: } ! 331: ! 332: //============================================================================= ! 333: ! 334: int MPATH_GetSocketAddr (int socket, struct qsockaddr *addr) ! 335: { ! 336: int addrlen = sizeof(struct qsockaddr); ! 337: unsigned int a; ! 338: ! 339: Q_memset(addr, 0, sizeof(struct qsockaddr)); ! 340: getsockname(socket, (struct sockaddr *)addr, &addrlen); ! 341: a = ((struct sockaddr_in *)addr)->sin_addr.s_addr; ! 342: if (a == 0 || a == inet_addr("127.0.0.1")) ! 343: ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr; ! 344: ! 345: return 0; ! 346: } ! 347: ! 348: //============================================================================= ! 349: ! 350: int MPATH_GetNameFromAddr (struct qsockaddr *addr, char *name) ! 351: { ! 352: struct hostent *hostentry; ! 353: ! 354: hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET); ! 355: if (hostentry) ! 356: { ! 357: Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1); ! 358: return 0; ! 359: } ! 360: ! 361: Q_strcpy (name, MPATH_AddrToString (addr)); ! 362: return 0; ! 363: } ! 364: ! 365: //============================================================================= ! 366: ! 367: int MPATH_GetAddrFromName(char *name, struct qsockaddr *addr) ! 368: { ! 369: struct hostent *hostentry; ! 370: ! 371: if (name[0] >= '0' && name[0] <= '9') ! 372: return PartialIPAddress (name, addr); ! 373: ! 374: hostentry = gethostbyname (name); ! 375: if (!hostentry) ! 376: return -1; ! 377: ! 378: addr->sa_family = AF_INET; ! 379: ((struct sockaddr_in *)addr)->sin_port = htons(net_hostport); ! 380: ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; ! 381: ! 382: return 0; ! 383: } ! 384: ! 385: //============================================================================= ! 386: ! 387: int MPATH_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) ! 388: { ! 389: if (addr1->sa_family != addr2->sa_family) ! 390: return -1; ! 391: ! 392: if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr) ! 393: return -1; ! 394: ! 395: if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port) ! 396: return 1; ! 397: ! 398: return 0; ! 399: } ! 400: ! 401: //============================================================================= ! 402: ! 403: int MPATH_GetSocketPort (struct qsockaddr *addr) ! 404: { ! 405: return ntohs(((struct sockaddr_in *)addr)->sin_port); ! 406: } ! 407: ! 408: ! 409: int MPATH_SetSocketPort (struct qsockaddr *addr, int port) ! 410: { ! 411: ((struct sockaddr_in *)addr)->sin_port = htons(port); ! 412: return 0; ! 413: } ! 414: ! 415: //=============================================================================
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.