i_net.c (6490B)
1 #include <stdlib.h> 2 #include <string.h> 3 #include <stdio.h> 4 5 #include <sys/socket.h> 6 #include <netinet/in.h> 7 #include <arpa/inet.h> 8 #include <errno.h> 9 #include <unistd.h> 10 #include <netdb.h> 11 #include <sys/ioctl.h> 12 13 #include "i_system.h" 14 #include "d_event.h" 15 #include "d_net.h" 16 #include "m_argv.h" 17 18 #include "doomstat.h" 19 20 #include "i_net.h" 21 22 /* 23 #define ntohl(x) \ 24 ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \ 25 (((unsigned long int)(x) & 0x0000ff00U) << 8) | \ 26 (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \ 27 (((unsigned long int)(x) & 0xff000000U) >> 24))) 28 29 #define ntohs(x) \ 30 ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \ 31 (((unsigned short int)(x) & 0xff00) >> 8))) \ 32 33 #define htonl(x) ntohl(x) 34 #define htons(x) ntohs(x) 35 */ 36 37 void NetSend (void); 38 boolean NetListen (void); 39 40 41 42 43 44 45 int DOOMPORT = (IPPORT_USERRESERVED +0x1d ); 46 47 int sendsocket; 48 int insocket; 49 50 struct sockaddr_in sendaddress[MAXNETNODES]; 51 52 void (*netget) (void); 53 void (*netsend) (void); 54 55 56 57 58 59 int UDPsocket (void) 60 { 61 int s; 62 63 64 s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP); 65 if (s<0) 66 I_Error ("can't create socket: %s",strerror(errno)); 67 68 return s; 69 } 70 71 72 73 74 void 75 BindToLocalPort 76 ( int s, 77 int port ) 78 { 79 int v; 80 struct sockaddr_in address; 81 82 memset (&address, 0, sizeof(address)); 83 address.sin_family = AF_INET; 84 address.sin_addr.s_addr = INADDR_ANY; 85 address.sin_port = port; 86 87 v = bind (s, (void *)&address, sizeof(address)); 88 if (v == -1) 89 I_Error ("BindToPort: bind: %s", strerror(errno)); 90 } 91 92 93 94 95 96 void PacketSend (void) 97 { 98 int c; 99 doomdata_t sw; 100 101 102 sw.checksum = htonl(netbuffer->checksum); 103 sw.player = netbuffer->player; 104 sw.retransmitfrom = netbuffer->retransmitfrom; 105 sw.starttic = netbuffer->starttic; 106 sw.numtics = netbuffer->numtics; 107 for (c=0 ; c< netbuffer->numtics ; c++) 108 { 109 sw.cmds[c].forwardmove = netbuffer->cmds[c].forwardmove; 110 sw.cmds[c].sidemove = netbuffer->cmds[c].sidemove; 111 sw.cmds[c].angleturn = htons(netbuffer->cmds[c].angleturn); 112 sw.cmds[c].consistancy = htons(netbuffer->cmds[c].consistancy); 113 sw.cmds[c].chatchar = netbuffer->cmds[c].chatchar; 114 sw.cmds[c].buttons = netbuffer->cmds[c].buttons; 115 } 116 117 118 c = sendto (sendsocket , &sw, doomcom->datalength 119 ,0,(void *)&sendaddress[doomcom->remotenode] 120 ,sizeof(sendaddress[doomcom->remotenode])); 121 122 123 124 } 125 126 127 128 129 130 void PacketGet (void) 131 { 132 int i; 133 int c; 134 struct sockaddr_in fromaddress; 135 unsigned int fromlen; 136 doomdata_t sw; 137 138 fromlen = sizeof(fromaddress); 139 c = recvfrom (insocket, &sw, sizeof(sw), 0, (struct sockaddr *)&fromaddress, &fromlen ); 140 if (c == -1 ) 141 { 142 if (errno != EWOULDBLOCK) 143 I_Error ("GetPacket: %s",strerror(errno)); 144 doomcom->remotenode = -1; 145 return; 146 } 147 148 { 149 static int first=1; 150 if (first) 151 printf("len=%d:p=[0x%x 0x%x] \n", c, *(int*)&sw, *((int*)&sw+1)); 152 first = 0; 153 } 154 155 156 for (i=0 ; i<doomcom->numnodes ; i++) 157 if ( fromaddress.sin_addr.s_addr == sendaddress[i].sin_addr.s_addr ) 158 break; 159 160 if (i == doomcom->numnodes) 161 { 162 163 doomcom->remotenode = -1; 164 return; 165 } 166 167 doomcom->remotenode = i; 168 doomcom->datalength = c; 169 170 171 netbuffer->checksum = ntohl(sw.checksum); 172 netbuffer->player = sw.player; 173 netbuffer->retransmitfrom = sw.retransmitfrom; 174 netbuffer->starttic = sw.starttic; 175 netbuffer->numtics = sw.numtics; 176 177 for (c=0 ; c< netbuffer->numtics ; c++) 178 { 179 netbuffer->cmds[c].forwardmove = sw.cmds[c].forwardmove; 180 netbuffer->cmds[c].sidemove = sw.cmds[c].sidemove; 181 netbuffer->cmds[c].angleturn = ntohs(sw.cmds[c].angleturn); 182 netbuffer->cmds[c].consistancy = ntohs(sw.cmds[c].consistancy); 183 netbuffer->cmds[c].chatchar = sw.cmds[c].chatchar; 184 netbuffer->cmds[c].buttons = sw.cmds[c].buttons; 185 } 186 } 187 188 189 190 int GetLocalAddress (void) 191 { 192 char hostname[1024]; 193 struct hostent* hostentry; 194 int v; 195 196 197 v = gethostname (hostname, sizeof(hostname)); 198 if (v == -1) 199 I_Error ("GetLocalAddress : gethostname: errno %d",errno); 200 201 hostentry = gethostbyname (hostname); 202 if (!hostentry) 203 I_Error ("GetLocalAddress : gethostbyname: couldn't get local host"); 204 205 return *(int *)hostentry->h_addr_list[0]; 206 } 207 208 209 210 211 212 void I_InitNetwork (void) 213 { 214 boolean trueval = true; 215 int i; 216 int p; 217 struct hostent* hostentry; 218 219 doomcom = malloc (sizeof (*doomcom) ); 220 memset (doomcom, 0, sizeof(*doomcom) ); 221 222 223 i = M_CheckParm ("-dup"); 224 if (i && i< myargc-1) 225 { 226 doomcom->ticdup = myargv[i+1][0]-'0'; 227 if (doomcom->ticdup < 1) 228 doomcom->ticdup = 1; 229 if (doomcom->ticdup > 9) 230 doomcom->ticdup = 9; 231 } 232 else 233 doomcom-> ticdup = 1; 234 235 if (M_CheckParm ("-extratic")) 236 doomcom-> extratics = 1; 237 else 238 doomcom-> extratics = 0; 239 240 p = M_CheckParm ("-port"); 241 if (p && p<myargc-1) 242 { 243 DOOMPORT = atoi (myargv[p+1]); 244 printf ("using alternate port %i\n",DOOMPORT); 245 } 246 247 248 249 i = M_CheckParm ("-net"); 250 if (!i) 251 { 252 253 netgame = false; 254 doomcom->id = DOOMCOM_ID; 255 doomcom->numplayers = doomcom->numnodes = 1; 256 doomcom->deathmatch = false; 257 doomcom->consoleplayer = 0; 258 return; 259 } 260 261 netsend = PacketSend; 262 netget = PacketGet; 263 netgame = true; 264 265 266 doomcom->consoleplayer = myargv[i+1][0]-'1'; 267 268 doomcom->numnodes = 1; 269 270 i++; 271 while (++i < myargc && myargv[i][0] != '-') 272 { 273 sendaddress[doomcom->numnodes].sin_family = AF_INET; 274 sendaddress[doomcom->numnodes].sin_port = htons(DOOMPORT); 275 if (myargv[i][0] == '.') 276 { 277 sendaddress[doomcom->numnodes].sin_addr.s_addr 278 = inet_addr (myargv[i]+1); 279 } 280 else 281 { 282 hostentry = gethostbyname (myargv[i]); 283 if (!hostentry) 284 I_Error ("gethostbyname: couldn't find %s", myargv[i]); 285 sendaddress[doomcom->numnodes].sin_addr.s_addr 286 = *(int *)hostentry->h_addr_list[0]; 287 } 288 doomcom->numnodes++; 289 } 290 291 doomcom->id = DOOMCOM_ID; 292 doomcom->numplayers = doomcom->numnodes; 293 294 295 insocket = UDPsocket (); 296 BindToLocalPort (insocket,htons(DOOMPORT)); 297 ioctl (insocket, FIONBIO, &trueval); 298 299 sendsocket = UDPsocket (); 300 } 301 302 303 void I_NetCmd (void) 304 { 305 if (doomcom->command == CMD_SEND) 306 { 307 netsend (); 308 } 309 else if (doomcom->command == CMD_GET) 310 { 311 netget (); 312 } 313 else 314 I_Error ("Bad net cmd: %i\n",doomcom->command); 315 } 316