1 /* Socket.c
2  *
3  * Kevin P. Smith 1/29/89 UDP stuff v1.0 by Andy McFadden  Feb-Apr 1992
4  *
5  * UDP protocol v1.0
6  *
7  * Routines to allow connection to the xtrek server.
8  */
9 #include "config.h"
10 #include "copyright2.h"
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <time.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <sys/time.h>
20 #include INC_SYS_SELECT
21 #include INC_MACHINE_ENDIAN
22 #include INC_NETINET_IN
23 #include INC_NETINET_TCP
24 #include <netdb.h>
25 #include <arpa/inet.h>
26 #include <math.h>
27 #include <errno.h>
28 #include "Wlib.h"
29 #include "defs.h"
30 #include "struct.h"
31 #include "data.h"
32 #include "packets.h"
33 #include "ltd_stats.h"
34 #include "wtext.h"
35 #include "playerlist.h"
36 
37 #include "badversion.h"
38 #include "defaults.h"
39 #include "dmessage.h"
40 #include "getship.h"
41 #include "local.h"
42 #include "map.h"
43 #include "netstat.h"
44 #include "newwin.h"
45 #include "reserved.h"
46 #include "playback.h"
47 #include "rotate.h"
48 #include "redraw.h"
49 #include "short.h"
50 #include "stats.h"
51 #include "udpopt.h"
52 #include "warning.h"
53 
54 #include "socket.h"
55 
56 #define statsFile stderr        /* use stderr for stats output for now */
57 int gather_stats = 0;
58 
59 #ifdef WIN32					 /* socket garbage in case *
60 						  * the client is not running
61 						  *
62 						  * * on NT */
63 #define read(f,b,l) recv(f,b,l,0)
64 #define write(f,b,l) send(f,b,l,0)
65 #define close(s) closesocket(s)
66 #endif
67 
68 #if 0
69 #define INCLUDE_SCAN            /* include Amdahl scanning beams */
70 #endif
71 #define INCLUDE_VISTRACT        /* include visible tractor beams */
72 
73 #define NETSTAT
74 
75 #ifdef GATEWAY
76 /* (these values are now defined in "main.c":) char *gw_mach        =
77  * "charon";     |client gateway; strcmp(serverName) int   gw_serv_port   =
78  * 5000;         |what to tell the server to use int   gw_port        = 5001;
79  * |where we will contact gw int   gw_local_port  = 5100;         |where we
80  * expect gw to contact us
81  *
82  * The client binds to "5100" and sends "5000" to the server (TCP).  The server
83  * sees that and sends a UDP packet to gw on port udp5000, which passes it
84  * through to port udp5100 on the client.  The client-gw gets the server's
85  * host and port from recvfrom.  (The client can't use the same method since
86  * these sockets are one-way only, so it connect()s to gw_port (udp5001) on
87  * the gateway machine regardless of what the server sends.)
88  *
89  * So all we need in .gwrc is: udp 5000 5001 tde.uts 5100
90  *
91  * assuming the client is on tde.uts.  Note that a UDP declaration will work for
92  * ANY server, but you need one per player, and the client has to have the
93  * port numbers in advance.
94  *
95  * If we're using a standard server, we're set.  If we're running through a
96  * gatewayed server, we have to do some unpleasant work on the server side... */
97 #endif
98 
99 void    handleMessage(struct mesg_spacket *packet);
100 void    handlePlyrInfo(struct plyr_info_spacket *packet);
101 void    handleKills(struct kills_spacket *packet);
102 void    handlePlayer(struct player_spacket *packet);
103 void    handleTorpInfo(struct torp_info_spacket *packet);
104 void    handleTorp(struct torp_spacket *packet);
105 void    handlePhaser(struct phaser_spacket *packet);
106 void    handlePlasmaInfo(struct plasma_info_spacket *packet);
107 void    handlePlasma(struct plasma_spacket *packet);
108 void    handleWarning(struct warning_spacket *packet);
109 void    handleMotd(struct motd_spacket *packet);
110 void    handleSelf(struct you_spacket *packet);
111 void    handleQueue(struct queue_spacket *packet);
112 void    handleStatus(struct status_spacket *packet);
113 void    handlePlanet(struct planet_spacket *packet);
114 void    handlePickok(struct pickok_spacket *packet);
115 void    handleLogin(struct login_spacket *packet);
116 void    handleFlags(struct flags_spacket *packet);
117 void    handleMask(struct mask_spacket *packet);
118 void    handlePStatus(struct pstatus_spacket *packet);
119 void    handleBadVersion(struct badversion_spacket *packet);
120 void    handleHostile(struct hostile_spacket *packet);
121 void    handleStats(struct stats_spacket *packet);
122 void    handlePlyrLogin(struct plyr_login_spacket *packet, int sock);
123 void    handleReserved(struct reserved_spacket *packet, int sock);
124 void    handlePlanetLoc(struct planet_loc_spacket *packet);
125 
126 #ifdef HANDLE_SCAN
127 void    handleScan(struct scan_spacket *packet);
128 
129 #endif
130 
131 void    handleUdpReply(struct udp_reply_spacket *packet);
132 void    handleSequence(struct sequence_spacket *packet);
133 
134 #ifdef RSA
135 void    handleRSAKey(struct rsa_key_spacket *packet);
136 extern void rsa_black_box(unsigned char *, unsigned char *, unsigned char *, unsigned char *);
137 #else
138 void    handleRSAKey(void *packet);
139 #endif
140 
141 void    handleShipCap(struct ship_cap_spacket *packet);
142 static void handleGeneric32(struct generic_32_spacket *packet);
143 extern void handlePing(struct ping_spacket *packet);	/* ping.c */
144 extern void terminate(int error);
145 
146 #ifdef SHORT_PACKETS
147 extern void handleShortReply(struct shortreply_spacket *packet);
148 extern void handleSMessage(struct mesg_s_spacket *packet);
149 extern void handleSWarning(struct warning_s_spacket *packet);
150 extern void handleSelfShort(struct youshort_spacket *packet);
151 extern void handleSelfShip(struct youss_spacket *packet);
152 extern void handleVPlayer(unsigned char *sbuf);
153 extern void handleVTorp(unsigned char *sbuf);
154 extern void handleVTorpInfo(unsigned char *sbuf);
155 extern void handleVPlanet(unsigned char *sbuf);
156 
157 /* S_P2 */
158 extern void handleVPhaser(unsigned char *sbuf);
159 extern void handleVKills(unsigned char *sbuf);
160 extern void handle_s_Stats(struct stats_s_spacket *packet);
161 
162 #endif /* SHORT_PACKETS */
163 
164 #ifdef FEATURE_PACKETS
165 extern void handleFeature(struct feature_cpacket *packet);
166 
167 #endif
168 void handleRank (struct rank_spacket *packet);
169 void handleLtd (struct ltd_spacket *packet);
170 
171 static void pickSocket(int old);
172 static int connUdpConn(void);
173 static int openUdpConn(void);
174 static int recvUdpConn(void);
175 static int doRead(int asock);
176 
177 char   *strcpyp_return(register char *s1, register char *s2, register int length);
178 
179 void
dummy(void)180         dummy(void)
181 {
182 }
183 
184 #ifdef SHORT_PACKETS
185 unsigned char numofbits[256] =
186 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1,
187  2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1,
188  2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
189  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1,
190  2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
191  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
192  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
193  4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1,
194  2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
195  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
196  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
197  4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2,
198  3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
199  4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
200  4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4,
201  5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
202 
203 static int vtsize[9] =
204 {4, 8, 8, 12, 12, 16, 20, 20, 24};		 /* How big is the torppacket
205 
206 						  *
207 						  *
208 						  */
209 int     vtisize[9] =
210 {4, 7, 9, 11, 13, 16, 18, 20, 22};		 /* 4 byte Header + torpdata */
211 
212 /* S_P2 */
213 int     shortversion = SHORTVERSION;		 /* Which version do we use? */
214 
215 #endif /* SHORT_PACKETS */
216 
217 #ifdef PACKET_LOG
218 void Log_Packet(char type, int act_size);
219 void Log_OPacket(int tpe, int size);
220 void print_opacket(char *packet, int size);
221 void print_packet(char *packet, int size);
222 #endif
223 
224 struct packet_handler handlers[] =
225 {
226   {0, NULL},					 /* record 0 */
227   {sizeof(struct mesg_spacket), handleMessage},	 /* SP_MESSAGE */
228   {sizeof(struct plyr_info_spacket), handlePlyrInfo},	/* SP_PLAYER_INFO */
229   {sizeof(struct kills_spacket), handleKills},	 /* SP_KILLS */
230   {sizeof(struct player_spacket), handlePlayer}, /* SP_PLAYER */
231   {sizeof(struct torp_info_spacket), handleTorpInfo},	/* SP_TORP_INFO */
232   {sizeof(struct torp_spacket), handleTorp},	 /* SP_TORP */
233   {sizeof(struct phaser_spacket), handlePhaser}, /* SP_PHASER */
234   {sizeof(struct plasma_info_spacket), handlePlasmaInfo},	/* SP_PLASMA_INFO
235 								 *
236 								 */
237   {sizeof(struct plasma_spacket), handlePlasma}, /* SP_PLASMA */
238   {sizeof(struct warning_spacket), handleWarning},	/* SP_WARNING */
239   {sizeof(struct motd_spacket), handleMotd},	 /* SP_MOTD */
240   {sizeof(struct you_spacket), handleSelf},	 /* SP_YOU */
241   {sizeof(struct queue_spacket), handleQueue},	 /* SP_QUEUE */
242   {sizeof(struct status_spacket), handleStatus}, /* SP_STATUS */
243   {sizeof(struct planet_spacket), handlePlanet}, /* SP_PLANET */
244   {sizeof(struct pickok_spacket), handlePickok}, /* SP_PICKOK */
245   {sizeof(struct login_spacket), handleLogin},	 /* SP_LOGIN */
246   {sizeof(struct flags_spacket), handleFlags},	 /* SP_FLAGS */
247   {sizeof(struct mask_spacket), handleMask},	 /* SP_MASK */
248   {sizeof(struct pstatus_spacket), handlePStatus},	/* SP_PSTATUS */
249   {sizeof(struct badversion_spacket), handleBadVersion},	/* SP_BADVERSION
250 								 *
251 								 */
252   {sizeof(struct hostile_spacket), handleHostile},	/* SP_HOSTILE */
253   {sizeof(struct stats_spacket), handleStats},	 /* SP_STATS */
254   {sizeof(struct plyr_login_spacket), handlePlyrLogin},		/* SP_PL_LOGIN
255 								 *
256 								 */
257   {sizeof(struct reserved_spacket), handleReserved},	/* SP_RESERVED */
258   {sizeof(struct planet_loc_spacket), handlePlanetLoc},		/* SP_PLANET_LOC
259 								 *
260 								 */
261 
262 #ifdef HANDLE_SCAN
263   {sizeof(struct scan_spacket), handleScan}	 /* SP_SCAN (ATM) */
264 #else
265   {0, dummy},					 /* won't be called */
266 #endif
267 
268   {sizeof(struct udp_reply_spacket), handleUdpReply},	/* SP_UDP_STAT */
269   {sizeof(struct sequence_spacket), handleSequence},	/* SP_SEQUENCE */
270   {sizeof(struct sc_sequence_spacket), handleSequence},		/* SP_SC_SEQUENCE
271 								 *
272 								 */
273 
274 #ifdef RSA
275   {sizeof(struct rsa_key_spacket), handleRSAKey},	/* SP_RSA_KEY */
276 #else
277   {0, dummy},					 /* #31, and dummy won't */
278 #endif
279 
280   {sizeof(struct generic_32_spacket), handleGeneric32}, /* SP_GENERIC_32 */
281   {0, dummy},					 /* 33 */
282   {0, dummy},					 /* 34 */
283   {0, dummy},					 /* 35 */
284   {0, dummy},					 /* 36 */
285   {0, dummy},					 /* 37 */
286   {0, dummy},					 /* 38 */
287   {sizeof(struct ship_cap_spacket), handleShipCap},	/* SP_SHIP_CAP */
288 
289 #ifdef SHORT_PACKETS
290   {sizeof(struct shortreply_spacket), handleShortReply},	/* SP_S_REPLY
291 								 *
292 								 */
293   {-1, handleSMessage},				 /* SP_S_MESSAGE */
294   {-1						 /* sizeof(struct *
295 						  * warning_s_spacket) */ , handleSWarning},
296 						 /* SP_S_WARNING */
297   {sizeof(struct youshort_spacket), handleSelfShort},	/* SP_S_YOU */
298   {sizeof(struct youss_spacket), handleSelfShip},	/* SP_S_YOU_SS */
299   {-1, /* variable */ handleVPlayer},		 /* SP_S_PLAYER */
300 #else
301   {0, dummy},					 /* 40 */
302   {0, dummy},					 /* 41 */
303   {0, dummy},					 /* 42 */
304   {0, dummy},					 /* 43 */
305   {0, dummy},					 /* 44 */
306   {0, dummy},					 /* 45 */
307 #endif
308   {sizeof(struct ping_spacket), handlePing},	 /* SP_PING */
309 
310 #ifdef SHORT_PACKETS
311   {-1, /* variable */ handleVTorp},		 /* SP_S_TORP */
312   {-1, handleVTorpInfo},			 /* SP_S_TORP_INFO */
313   {20, handleVTorp},				 /* SP_S_8_TORP */
314   {-1, handleVPlanet},				 /* SP_S_PLANET */
315 #else
316   {0, dummy},					 /* 47 */
317   {0, dummy},					 /* 48 */
318   {0, dummy},					 /* 49 */
319   {0, dummy},					 /* 50 */
320 #endif
321 
322   {0, dummy},					 /* 51 */
323   {0, dummy},					 /* 52 */
324   {0, dummy},					 /* 53 */
325   {0, dummy},					 /* 54 */
326   {0, dummy},					 /* 55 */
327 
328 #ifdef SHORT_PACKETS				 /* S_P2 */
329   {0, dummy},					 /* SP_S_SEQUENCE not yet * *
330 						  * implemented */
331   {-1, handleVPhaser},				 /* SP_S_PHASER */
332   {-1, handleVKills},				 /* SP_S_KILLS */
333   {sizeof(struct stats_s_spacket), handle_s_Stats},	/* SP_S_STATS */
334 #else
335   {0, dummy},					 /* 56 */
336   {0, dummy},					 /* 57 */
337   {0, dummy},					 /* 58 */
338   {0, dummy},					 /* 59 */
339 #endif
340 
341 #ifdef FEATURE_PACKETS
342   {sizeof(struct feature_cpacket), handleFeature},	/* SP_FEATURE; 60 */
343 #endif
344   {sizeof(struct rank_spacket), handleRank},	/* SP_RANK; 61 */
345   {sizeof(struct ltd_spacket), handleLtd},	/* SP_LTD; 62 */
346 
347 };
348 
349 int     sizes[] =
350 {
351   0,						 /* record 0 */
352   sizeof(struct mesg_cpacket),			 /* CP_MESSAGE */
353   sizeof(struct speed_cpacket),			 /* CP_SPEED */
354   sizeof(struct dir_cpacket),			 /* CP_DIRECTION */
355   sizeof(struct phaser_cpacket),		 /* CP_PHASER */
356   sizeof(struct plasma_cpacket),		 /* CP_PLASMA */
357   sizeof(struct torp_cpacket),			 /* CP_TORP */
358   sizeof(struct quit_cpacket),			 /* CP_QUIT */
359   sizeof(struct login_cpacket),			 /* CP_LOGIN */
360   sizeof(struct outfit_cpacket),		 /* CP_OUTFIT */
361   sizeof(struct war_cpacket),			 /* CP_WAR */
362   sizeof(struct practr_cpacket),		 /* CP_PRACTR */
363   sizeof(struct shield_cpacket),		 /* CP_SHIELD */
364   sizeof(struct repair_cpacket),		 /* CP_REPAIR */
365   sizeof(struct orbit_cpacket),			 /* CP_ORBIT */
366   sizeof(struct planlock_cpacket),		 /* CP_PLANLOCK */
367   sizeof(struct playlock_cpacket),		 /* CP_PLAYLOCK */
368   sizeof(struct bomb_cpacket),			 /* CP_BOMB */
369   sizeof(struct beam_cpacket),			 /* CP_BEAM */
370   sizeof(struct cloak_cpacket),			 /* CP_CLOAK */
371   sizeof(struct det_torps_cpacket),		 /* CP_DET_TORPS */
372   sizeof(struct det_mytorp_cpacket),		 /* CP_DET_MYTORP */
373   sizeof(struct copilot_cpacket),		 /* CP_COPILOT */
374   sizeof(struct refit_cpacket),			 /* CP_REFIT */
375   sizeof(struct tractor_cpacket),		 /* CP_TRACTOR */
376   sizeof(struct repress_cpacket),		 /* CP_REPRESS */
377   sizeof(struct coup_cpacket),			 /* CP_COUP */
378   sizeof(struct socket_cpacket),		 /* CP_SOCKET */
379   sizeof(struct options_cpacket),		 /* CP_OPTIONS */
380   sizeof(struct bye_cpacket),			 /* CP_BYE */
381   sizeof(struct dockperm_cpacket),		 /* CP_DOCKPERM */
382   sizeof(struct updates_cpacket),		 /* CP_UPDATES */
383   sizeof(struct resetstats_cpacket),		 /* CP_RESETSTATS */
384   sizeof(struct reserved_cpacket),		 /* CP_RESERVED */
385 
386 #ifdef INCLUDE_SCAN
387   sizeof(struct scan_cpacket),			 /* CP_SCAN (ATM) */
388 #else
389   0,
390 #endif
391   sizeof(struct udp_req_cpacket),		 /* CP_UDP_REQ */
392   sizeof(struct sequence_cpacket),		 /* CP_SEQUENCE */
393 
394 #ifdef RSA
395   sizeof(struct rsa_key_cpacket),		 /* CP_RSA_KEY */
396 #else
397   0,						 /* 37 */
398 #endif
399 
400   0,						 /* 38 */
401   0,						 /* 39 */
402   0,						 /* 40 */
403   0,						 /* 41 */
404 
405 #ifdef PING
406   sizeof(struct ping_cpacket),			 /* CP_PING_RESPONSE */
407 #else
408   0,
409 #endif
410 
411 #ifdef SHORT_PACKETS
412   sizeof(struct shortreq_cpacket),		 /* CP_S_REQ */
413   sizeof(struct threshold_cpacket),		 /* CP_S_THRS */
414   -1,						 /* CP_S_MESSAGE */
415 #else
416   0,						 /* 43 */
417   0,						 /* 44 */
418   0,						 /* 45 */
419 #endif
420 
421   0,						 /* 46 */
422   0,						 /* 47 */
423   0,						 /* 48 */
424   0,						 /* 49 */
425   0,						 /* 50 */
426   0,						 /* 51 */
427   0,						 /* 52 */
428   0,						 /* 53 */
429   0,						 /* 54 */
430   0,						 /* 55 */
431   0,						 /* 56 */
432   0,						 /* 57 */
433   0,						 /* 58 */
434   0,						 /* 59 */
435 
436 #ifdef FEATURE_PACKETS
437   sizeof(struct feature_cpacket),		 /* CP_FEATURE; 60 */
438 #endif
439 
440 };
441 
442 #define NUM_PACKETS (sizeof(handlers) / sizeof(handlers[0]) - 1)
443 #define NUM_SIZES (sizeof(sizes) / sizeof(sizes[0]) - 1)
444 
445 
446 #ifdef PACKET_LOG
447 /* stuff useful for logging server packets to see how much bandwidth netrek
448  * is really using */
449 int     log_packets = 0;			 /* whether or not to be
450 						  * logging packets */
451 int     packet_log[NUM_PACKETS];		 /* number of packets logged */
452 int     outpacket_log[NUM_SIZES];
453 int     ALL_BYTES = 0;				 /* To log all bytes */
454 #endif /* PACKET_LOG */
455 
456 int     serverDead = 0;
457 
458 #define BUFSIZE 1024
459 char    buf[BUFSIZE];
460 
461 static int udpLocalPort = 0;
462 static int udpServerPort = 0;
463 static LONG serveraddr = 0;
464 static LONG sequence = 0;
465 static int drop_flag = 0;
466 static int chan = -1;				 /* tells sequence checker *
467 
468 						  *
469 						  * * where packet is from */
470 static short fSpeed, fDirection, fShield, fOrbit, fRepair, fBeamup, fBeamdown,
471         fCloak, fBomb, fDockperm, fPhaser, fPlasma, fPlayLock, fPlanLock,
472         fTractor, fRepress;
473 
474 /* internal prototypes */
475 static void dotimers(void);
476 
477 /* print the SP_S_TORP* packets.  */
478 /* sbuf = pointer to packet buff  */
479 /* type=1 print SP_S_TORP         */
480 /* type=2 print SP_S_8_TORP       */
481 /* type=3 print SP_S_TORP_INFO    */
print_sp_s_torp(char * sbuf,int type)482 void print_sp_s_torp(char *sbuf, int type)
483 {
484   unsigned char which, *data, infobitset, *infodata;
485   unsigned char bitset;
486   int     dx, dy;
487   int     shiftvar;
488   int     i;
489   char    status, war;
490   register int shift = 0;                      /* How many torps are
491                                                 * * extracted (for shifting) */
492 
493   if ( (type == 1) || (type == 2) )
494     {
495       /* now we must find the data ... :-) */
496       if (sbuf[0] == SP_S_8_TORP)
497 	{						 /* MAX packet */
498 	  bitset = 0xff;
499 	  which = sbuf[1];
500 	  data = (unsigned char *) &sbuf[2];
501 	}
502       else
503 	{						 /* Normal Packet */
504 	  bitset = sbuf[1];
505 	  which = sbuf[2];
506 	  data = (unsigned char *) &sbuf[3];
507 	}
508       fprintf(stderr, "  bitset=0x%0X, which=%d, ", bitset, which);
509 #ifdef CORRUPTED_PACKETS
510       /* we probably should do something clever here - jmn */
511 #endif
512 
513       for (shift = 0, i = 0; i < 8; i++, bitset >>= 1)
514 	{
515 	  if (bitset & 01)
516 	    {
517 	      dx = (*data >> shift);
518 	      data++;
519 	      shiftvar = (unsigned char) *data;	 /* to silence gcc */
520 	      shiftvar <<= (8 - shift);
521 	      dx |= (shiftvar & 511);
522 	      shift++;
523 	      dy = (*data >> shift);
524 	      data++;
525 	      shiftvar = (unsigned char) *data;	 /* to silence gcc */
526 	      shiftvar <<= (8 - shift);
527 	      dy |= (shiftvar & 511);
528 	      shift++;
529 	      if (shift == 8)
530 		{
531 		  shift = 0;
532 		  data++;
533 		}
534 	      fprintf(stderr, "dx=%d, dy=%d, ",dx, dy);
535 	    }
536 	}
537     }
538   else if (type == 3)
539     {
540       /* now we must find the data ... :-) */
541       bitset = sbuf[1];
542       which = sbuf[2];
543       infobitset = sbuf[3];
544       /* Where is the data ? */
545       data = (unsigned char *) &sbuf[4];
546 
547       fprintf(stderr, "  bitset=0x%0X, which=%d, infobitset=0x%0X, ",
548 	      bitset, which, infobitset);
549 
550       infodata = (unsigned char *) &sbuf[vtisize[numofbits[(unsigned char) sbuf[1]]]];
551 
552       for (shift = 0, i = 0; i < 8; bitset >>= 1, infobitset >>= 1, i++)
553 	{
554 	  if (bitset & 01)
555 	    {
556 	      dx = (*data >> shift);
557 	      data++;
558 	      shiftvar = (unsigned char) *data;	 /* to silence gcc */
559 	      shiftvar <<= (8 - shift);
560 	      dx |= (shiftvar & 511);
561 	      shift++;
562 	      dy = (*data >> shift);
563 	      data++;
564 	      shiftvar = (unsigned char) *data;	 /* to silence gcc */
565 	      shiftvar <<= (8 - shift);
566 	      dy |= (shiftvar & 511);
567 	      shift++;
568 	      if (shift == 8)
569 		{
570 		  shift = 0;
571 		  data++;
572 		}
573 	      fprintf(stderr, "dx=%d, dy=%d, ",dx, dy);
574 	    }
575 
576 	  /* Now the TorpInfo */
577 	  if (infobitset & 01)
578 	    {
579 	      war = (unsigned char) *infodata & 15 /* 0x0f */ ;
580 	      status = ((unsigned char) *infodata & 0xf0) >> 4;
581 	      infodata++;
582 	      fprintf(stderr, "war=0x%0X, status=0x%0X, ", war, status);
583 	    }					 /* if */
584 
585 	}						 /* for */
586 
587     }
588 }
589 
590 /* reset all the "force command" variables */
resetForce(void)591 static void resetForce(void)
592 {
593   fSpeed = fDirection = fShield = fOrbit = fRepair = fBeamup = fBeamdown =
594       fCloak = fBomb = fDockperm = fPhaser = fPlasma = fPlayLock = fPlanLock =
595       fTractor = fRepress = -1;
596 }
597 
598 /* If something we want to happen hasn't yet, send it again.
599  *
600  * The low byte is the request, the high byte is a max count.  When the max
601  * count reaches zero, the client stops trying.  Checking is done with a
602  * macro for speed & clarity. */
603 #define FCHECK_FLAGS(flag, force, const) {                      \
604         if (force > 0) {                                        \
605             if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) {  \
606                 speedReq.type = const;                          \
607                 speedReq.speed = (force & 0xff);                \
608                 sendServerPacket((struct player_spacket *) &speedReq);  \
609                 V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff));     \
610                 force -= 0x100;                                 \
611                 if (force < 0x100) force = -1;  /* give up */   \
612             } else                                              \
613                 force = -1;                                     \
614         }                                                       \
615 }
616 #define FCHECK_VAL(value, force, const) {                       \
617         if (force > 0) {                                        \
618             if ((value) != (force & 0xff)) {                    \
619                 speedReq.type = const;                          \
620                 speedReq.speed = (force & 0xff);                \
621                 sendServerPacket((struct player_spacket *) &speedReq);  \
622                 V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff));     \
623                 force -= 0x100;                                 \
624                 if (force < 0x100) force = -1;  /* give up */   \
625             } else                                              \
626                 force = -1;                                     \
627         }                                                       \
628 }
629 #define FCHECK_TRACT(flag, force, const) {                      \
630         if (force > 0) {                                        \
631             if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) {  \
632                 tractorReq.type = const;                        \
633                 tractorReq.state = ((force & 0xff) >= 0x40);    \
634                 tractorReq.pnum = (force & 0xff) & (~0x40);     \
635                 sendServerPacket((struct player_spacket *)&tractorReq); \
636                 V_UDPDIAG(("Forced %d:%d/%d\n", const,          \
637                         tractorReq.state, tractorReq.pnum));    \
638                 force -= 0x100;                                 \
639                 if (force < 0x100) force = -1;  /* give up */   \
640             } else                                              \
641                 force = -1;                                     \
642         }                                                       \
643 }
644 
checkForce(void)645 void checkForce(void)
646 {
647   struct speed_cpacket speedReq;
648   struct tractor_cpacket tractorReq;
649 
650   FCHECK_VAL(me->p_speed, fSpeed, CP_SPEED);	 /* almost always repeats */
651 
652 #ifdef nodef					 /* not needed */
653   FCHECK_VAL(me->p_dir, fDirection, CP_DIRECTION);	/* (ditto) */
654 #endif
655 
656   FCHECK_FLAGS(PFSHIELD, fShield, CP_SHIELD);
657   FCHECK_FLAGS(PFORBIT, fOrbit, CP_ORBIT);
658   FCHECK_FLAGS(PFREPAIR, fRepair, CP_REPAIR);
659   FCHECK_FLAGS(PFBEAMUP, fBeamup, CP_BEAM);
660   FCHECK_FLAGS(PFBEAMDOWN, fBeamdown, CP_BEAM);
661   FCHECK_FLAGS(PFCLOAK, fCloak, CP_CLOAK);
662   FCHECK_FLAGS(PFBOMB, fBomb, CP_BOMB);
663   FCHECK_FLAGS(PFDOCKOK, fDockperm, CP_DOCKPERM);
664   FCHECK_VAL(phasers[me->p_no].ph_status, fPhaser, CP_PHASER);	/* bug: dir 0
665 								 *
666 								 */
667   FCHECK_VAL(plasmatorps[me->p_no].pt_status, fPlasma, CP_PLASMA);	/* (ditto)
668 									 *
669 									 */
670   FCHECK_FLAGS(PFPLOCK, fPlayLock, CP_PLAYLOCK);
671   FCHECK_FLAGS(PFPLLOCK, fPlanLock, CP_PLANLOCK);
672 
673   FCHECK_TRACT(PFTRACT, fTractor, CP_TRACTOR);
674   FCHECK_TRACT(PFPRESS, fRepress, CP_REPRESS);
675 }
676 
connectToServer(int port)677 void connectToServer(int port)
678 {
679   int     s;
680   struct sockaddr_in addr;
681   struct sockaddr_in naddr;
682   socklen_t len;
683   fd_set  readfds;
684   struct timeval timeout;
685   struct hostent *hp;
686   int     optval;
687 
688   serverDead = 0;
689   if (sock != -1)
690     {
691       shutdown(sock, 2);
692       close(sock);
693       sock = -1;
694     }
695 
696 #ifdef nodef
697   sleep(3);					 /* I think this is necessary
698 						  * * * for some unknown
699 						  * reason */
700 #endif
701 
702   printf("Waiting for connection (port %d). \n", port);
703 
704   if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
705     {
706       printf("I can't create a socket\n");
707       terminate(2);
708     }
709 
710   /* allow local address resuse */
711   optval = 1;
712   if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof(int))
713       < 0)
714     {
715       perror("setsockopt");
716     }
717 
718   addr.sin_family = AF_INET;
719   addr.sin_addr.s_addr = INADDR_ANY;
720   addr.sin_port = htons(port);
721 
722   if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0)
723     {
724 
725 #ifdef nodef
726       sleep(10);
727       if (bind(s, &addr, sizeof(addr)) < 0)
728 	{
729 	  sleep(10);
730 	  if (bind(s, &addr, sizeof(addr)) < 0)
731 	    {
732 	      printf("I can't bind to port!\n");
733 	      terminate(3);
734 	    }
735 	}
736 #endif
737 
738       perror("bind");				 /* NEW */
739       terminate(1);
740     }
741   if (listen(s, 1) < 0)
742     perror("listen");
743 
744   len = sizeof(naddr);
745 
746 tryagain:
747   timeout.tv_sec = 240;				 /* four minutes */
748   timeout.tv_usec = 0;
749   FD_ZERO(&readfds);
750   FD_SET(s, &readfds);
751 
752   if (s >= max_fd)
753     max_fd = s + 1;
754 
755   if (SELECT(max_fd, &readfds, NULL, NULL, &timeout) == 0)
756     {
757       printf("Well, I think the server died!\n");
758       terminate(0);
759     }
760 
761   sock = accept(s, (struct sockaddr *) &naddr, &len);
762 
763   if (sock == -1)
764     {
765       goto tryagain;
766     }
767 
768   if (sock >= max_fd)
769     max_fd = sock + 1;
770 
771   printf("Got connection.\n");
772 
773   close(s);
774   pickSocket(port);				 /* new socket != port */
775 
776 
777   /* This is necessary; it tries to determine who the caller is, and set * *
778    * "serverName" and "serveraddr" appropriately. */
779   len = sizeof(struct sockaddr_in);
780 
781   if (getpeername(sock, (struct sockaddr *) &addr, &len) < 0)
782     {
783       perror("unable to get peername");
784       serverName = "nowhere";
785       printf("Connection from server\n");
786     }
787   else
788     {
789       serveraddr = addr.sin_addr.s_addr;
790       hp = gethostbyaddr((char *) &addr.sin_addr.s_addr, sizeof(LONG), AF_INET);
791       if (hp != NULL)
792 	{
793 	  serverName = (char *) malloc(strlen(hp->h_name) + 1);
794 	  strcpy(serverName, hp->h_name);
795 	  printf("Connection from server %s (%s)\n", serverName, inet_ntoa(addr.sin_addr));
796 	}
797       else
798 	{
799 	  serverName = (char *) malloc(strlen(inet_ntoa(addr.sin_addr)) + 1);
800 	  strcpy(serverName, inet_ntoa(addr.sin_addr));
801 	  printf("Connection from server %s\n", serverName);
802 	}
803     }
804 
805 }
806 
807 
set_tcp_opts(int s)808 static void set_tcp_opts(int s)
809 {
810   int     optval = 1;
811   struct protoent *ent;
812 
813   ent = getprotobyname("TCP");
814   if (!ent)
815     {
816       fprintf(stderr, "TCP protocol not found.\n");
817       return;
818     }
819   if (setsockopt(s, ent->p_proto, TCP_NODELAY, &optval, sizeof(int)) < 0)
820             perror("setsockopt");
821 }
822 
823 #ifdef nodef
set_udp_opts(int s)824 static void set_udp_opts(int s)
825 {
826   int     optval = BUFSIZ;
827   struct protoent *ent;
828 
829   ent = getprotobyname("UDP");
830   if (!ent)
831     {
832       fprintf(stderr, "UDP protocol not found.\n");
833       return;
834     }
835   if (setsockopt(s, ent->p_proto, SO_RCVBUF, &optval, sizeof(int)) < 0)
836             perror("setsockopt");
837 }
838 #endif
839 
callServer(int port,char * server)840 void callServer(int port, char *server)
841 {
842   int     s;
843   struct sockaddr_in addr;
844   struct hostent *hp;
845 
846   serverDead = 0;
847 
848   fprintf(stderr, "connecting to %s on port %d\n", server, port);
849 
850   if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
851     {
852       perror("failed in socket");
853       terminate(1);
854     }
855   set_tcp_opts(s);
856   addr.sin_family = AF_INET;
857   addr.sin_port = htons(port);
858 
859   if ((addr.sin_addr.s_addr = inet_addr(server)) == -1)
860     {
861       if ((hp = gethostbyname(server)) == NULL)
862 	{
863 	  printf("unable to resolve hostname %s\n", server);
864 	  terminate(1);
865 	}
866       else
867 	{
868 	  addr.sin_addr.s_addr = *(LONG *) hp->h_addr;
869 	}
870     }
871   serveraddr = addr.sin_addr.s_addr;
872 
873   if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0)
874     {
875       perror("failed in connect");
876       fprintf(stderr, "connection failed\n");
877       terminate(1);
878     }
879   fprintf(stderr, "connected\n");
880 
881   sock = s;
882 
883   if (sock >= max_fd)
884     max_fd = sock + 1;
885 
886 #ifdef TREKHOPD
887   /* We use a different scheme from gw: we tell the server who we want to * *
888    * connect to and what our local UDP port is; it picks its own UDP ports *
889    * * and tells us what they are.  This is MUCH more flexible and avoids a *
890    * * number of problems, and may come in handy if the blessed scheme
891    * changes. * * It's also slightly more work. */
892   {
893     extern int port_req, use_trekhopd, serv_port;
894     extern char *host_req;
895     struct mesg_cpacket msg;
896     struct mesg_spacket reply;
897     int     n, count, *ip;
898     char   *buf;
899 
900     if (use_trekhopd)
901       {
902 	msg.type = SP_MESSAGE;
903 	msg.group = msg.indiv = msg.pad1 = 0;
904 	ip = (int *) msg.mesg;
905 	*(ip++) = htons(port_req);
906 	*(ip++) = htons(gw_local_port);
907 	STRNCPY(msg.mesg + 8, login, 8);
908 	strcpy(msg.mesg + 16, host_req);
909 	if (gwrite(s, &msg, sizeof(struct mesg_cpacket)) < 0)
910 	  {
911 	    fprintf(stderr, "trekhopd init failure\n");
912 	    terminate(1);
913 	  }
914 	printf("--- trekhopd request sent, awaiting reply\n");
915 	/* now block waiting for reply */
916 	count = sizeof(struct mesg_spacket);
917 
918 	for (buf = (char *) &reply; count; buf += n, count -= n)
919 	  {
920 	    if ((n = read(s, buf, count)) <= 0)
921 	      {
922 		perror("trekhopd read");
923 		terminate(1);
924 	      }
925 	  }
926 
927 	if (reply.type != SP_MESSAGE)
928 	  {
929 	    fprintf(stderr, "Got bogus reply from trekhopd (%d)\n",
930 		    reply.type);
931 	    terminate(1);
932 	  }
933 	ip = (int *) reply.mesg;
934 	gw_serv_port = ntohl(*ip++);
935 	gw_port = ntohl(*ip++);
936 	serv_port = ntohl(*ip++);
937 	printf("--- trekhopd reply received\n");
938 
939 	/* printf("ports = %d/%d, %d\n", gw_serv_port, gw_port, serv_port); */
940       }
941   }
942 #endif /* TREKHOPD */
943 
944   pickSocket(port);				 /* new socket != port */
945 }
946 
isServerDead(void)947 int isServerDead(void)
948 {
949   return serverDead;
950 }
951 
socketPauseCommon(int wake_on_user_input)952 void socketPauseCommon(int wake_on_user_input)
953 {
954   struct timeval timeout;
955   fd_set  readfds;
956   int retval;
957 
958   timeout.tv_sec = 1;
959   timeout.tv_usec = 0;
960 
961   FD_ZERO(&readfds);
962   FD_SET(sock, &readfds);
963   if (udpSock >= 0)				 /* new */
964     FD_SET(udpSock, &readfds);
965 #ifndef HAVE_WIN32
966   if (wake_on_user_input)
967     FD_SET(W_Socket(), &readfds);
968 #endif
969 
970   retval = SELECT(max_fd, &readfds, 0, 0, &timeout);
971   if (retval < 0) perror("select"); /* FIXME: EBADF on kill of ntserv during outfit */
972 }
973 
socketPauseNoUser(void)974 void socketPauseNoUser(void)
975 {
976   socketPauseCommon(0);
977 }
978 
socketPause(void)979 void socketPause(void)
980 {
981   socketPauseCommon(1);
982 }
983 
readFromServer(fd_set * readfds)984 int readFromServer(fd_set *readfds)
985 {
986   int     retval = 0;
987 
988   if (serverDead)
989     return 0;
990 
991   if (!readfds)
992     {
993       struct timeval timeout;
994       int     rs;
995       fd_set  mask;
996 
997       readfds = &mask;
998 
999       FD_ZERO(readfds);
1000       FD_SET(sock, readfds);
1001       if (udpSock >= 0)
1002 	FD_SET(udpSock, readfds);
1003       timeout.tv_sec = 0;
1004       timeout.tv_usec = 0;
1005       if ((rs = SELECT(max_fd, readfds, 0, 0, &timeout)) == 0)
1006 	{
1007 	  dotimers();
1008 	  return 0;
1009 	}
1010       if (rs < 0) {
1011 	if (errno == EINTR) return 0;
1012 	perror("select");
1013 	sleep(1);
1014       }
1015     }
1016   if (udpSock >= 0 && FD_ISSET(udpSock, readfds))
1017     {
1018       /* WAS V_ */
1019       UDPDIAG(("Activity on UDP socket\n"));
1020       chan = udpSock;
1021       if (commStatus == STAT_VERIFY_UDP)
1022 	{
1023 	  sequence = 0;				 /* reset sequence #s */
1024 	  resetForce();
1025 
1026 	  printUdpInfo();
1027 	  UDPDIAG(("UDP connection established.\n"));
1028 
1029 	  commMode = COMM_UDP;
1030 	  commStatus = STAT_CONNECTED;
1031 	  commSwitchTimeout = 0;
1032 	  if (udpClientRecv != MODE_SIMPLE)
1033 	    sendUdpReq(COMM_MODE + udpClientRecv);
1034 	  if (udpWin)
1035 	    {
1036 	      udprefresh(UDP_CURRENT);
1037 	      udprefresh(UDP_STATUS);
1038 	    }
1039 	}
1040       retval += doRead(udpSock);
1041     }
1042 
1043   /* Read info from the xtrek server */
1044   if (FD_ISSET(sock, readfds))
1045     {
1046       chan = sock;
1047       if (commMode == COMM_TCP)
1048 	drop_flag = 0;				 /* just in case */
1049       /* Bug fix for unnecessary redraws with UDP on - reported by TP */
1050       //      if (commMode == COMM_UDP)
1051       //	doRead (sock);
1052       //      else
1053 	retval += doRead (sock);
1054     }
1055 
1056   dotimers();
1057   return retval != 0;				 /* convert to 1/0 */
1058 }
1059 
dotimers(void)1060 static void dotimers(void)
1061 {
1062   /* if switching comm mode, decrement timeout counter */
1063   if (commSwitchTimeout > 0)
1064     {
1065       if (!(--commSwitchTimeout))
1066 	{
1067 	  /* timed out; could be initial request to non-UDP server (which * *
1068 	   * won't be answered), or the verify packet got lost en route to *
1069 	   * * the server.  Could also be a request for TCP which timed out *
1070 	   * * (weird), in which case we just reset anyway. */
1071 	  commModeReq = commMode = COMM_TCP;
1072 	  commStatus = STAT_CONNECTED;
1073 	  if (udpSock >= 0)
1074 	    closeUdpConn();
1075 	  if (udpWin)
1076 	    {
1077 	      udprefresh(UDP_CURRENT);
1078 	      udprefresh(UDP_STATUS);
1079 	    }
1080 	  warning("Timed out waiting for UDP response from server");
1081 	  UDPDIAG(("Timed out waiting for UDP response from server\n"));
1082 	}
1083     }
1084   /* if we're in a UDP "force" mode, check to see if we need to do something */
1085   if (udpClientSend > 1 && commMode == COMM_UDP)
1086     checkForce();
1087 }
1088 
1089 int
getvpsize(char * bufptr)1090         getvpsize(char *bufptr)
1091 {
1092   int     size;
1093 
1094   switch (*bufptr)
1095     {
1096     case SP_S_MESSAGE:
1097       size = ((unsigned char) bufptr[4]);	 /* IMPORTANT  Changed */
1098       break;
1099     case SP_S_WARNING:
1100       if ((unsigned char) bufptr[1] == STEXTE_STRING ||
1101 	  (unsigned char) bufptr[1] == SHORT_WARNING)
1102 	{
1103 	  size = ((unsigned char) bufptr[3]);
1104 	}
1105       else
1106 	size = 4;				 /* Normal Packet */
1107       break;
1108     case SP_S_PLAYER:
1109       if ((unsigned char) bufptr[1] & (unsigned char) 128)
1110 	{					 /* Small +extended Header */
1111 	  size = ((unsigned char) (bufptr[1] & 0x3f) * 4) + 4;
1112 	}
1113       else if ((unsigned char) bufptr[1] & 64)
1114 	{					 /* Small Header */
1115 	  if (shortversion >= SHORTVERSION)	 /* S_P2 */
1116 	    size = ((unsigned char) (bufptr[1] & 0x3f) * 4) + 4 + (bufptr[2] * 4);
1117 	  else
1118 	    size = ((unsigned char) (bufptr[1] & 0x3f) * 4) + 4;
1119 	}
1120       else
1121 	{					 /* Big Header */
1122 	  size = ((unsigned char) bufptr[1] * 4 + 12);
1123 	}
1124       break;
1125     case SP_S_TORP:
1126       size = vtsize[numofbits[(unsigned char) bufptr[1]]];
1127       break;
1128     case SP_S_TORP_INFO:
1129       size = (vtisize[numofbits[(unsigned char) bufptr[1]]]
1130 	      + numofbits[(unsigned char) bufptr[3]]);
1131       break;
1132     case SP_S_PLANET:
1133       size = ((unsigned char) bufptr[1] * VPLANET_SIZE) + 2;
1134       break;
1135     case SP_S_PHASER:				 /* S_P2 */
1136       switch ((unsigned char) bufptr[1] & 0x0f)
1137 	{
1138 	case PHFREE:
1139 	case PHHIT:
1140 	case PHMISS:
1141 	  size = 4;
1142 	  break;
1143 	case PHHIT2:
1144 	  size = 8;
1145 	  break;
1146 	default:
1147 	  size = sizeof(struct phaser_s_spacket);
1148 
1149 	  break;
1150 	}
1151       break;
1152     case SP_S_KILLS:				 /* S_P2 */
1153       size = ((unsigned char) bufptr[1] * 2) + 2;
1154       break;
1155     default:
1156       fprintf(stderr, "Unknown variable packet\n");
1157       /* terminate(1); */
1158       return -1;
1159       break;
1160     }
1161   if ((size % 4) != 0)
1162     {
1163       size += (4 - (size % 4));
1164     }
1165 
1166   return size;
1167 }
1168 
doRead(int asock)1169 static int doRead(int asock)
1170 {
1171   struct timeval timeout;
1172   fd_set  readfds;
1173   char   *bufptr;
1174   int     size;
1175   int     count;
1176   int     temp;
1177 
1178   timeout.tv_sec = 0;
1179   timeout.tv_usec = 0;
1180 
1181   count = read(asock, buf, BUFSIZE);
1182 
1183 #ifdef NETSTAT
1184   if (netstat &&
1185       (asock == udpSock ||
1186        commMode != COMM_UDP ||
1187        udpClientRecv == MODE_TCP))
1188     {
1189       ns_record_update(count);
1190     }
1191 #endif
1192 
1193   if (debug)
1194     printf("read %d bytes from %s socket\n",
1195 	   count, asock == udpSock ? "UDP" : "TCP");
1196 
1197   if (count <= 0)
1198     {
1199       if (asock == udpSock)
1200 	{
1201 
1202 #ifndef WIN32
1203 	  if (errno == ECONNREFUSED)
1204 #else
1205 	  if (WSAGetLastError() == WSAECONNREFUSED)
1206 #endif
1207 
1208 	    {
1209 	      struct sockaddr_in addr;
1210 
1211 	      UDPDIAG(("asock=%d, sock=%d, udpSock=%d, errno=%d\n",
1212 		       asock, sock, udpSock, errno));
1213 	      UDPDIAG(("count=%d\n", count));
1214 	      UDPDIAG(("Hiccup(%d)!  Reconnecting\n", errno));
1215 	      addr.sin_addr.s_addr = serveraddr;
1216 	      addr.sin_port = htons(udpServerPort);
1217 	      addr.sin_family = AF_INET;
1218 	      if (connect(udpSock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
1219 		{
1220 		  perror("connect");
1221 		  UDPDIAG(("Unable to reconnect\n"));
1222 		  /* and fall through to disconnect */
1223 		}
1224 	      else
1225 		{
1226 		  UDPDIAG(("Reconnect successful\n"));
1227 		  return 0;
1228 		}
1229 	    }
1230 	  UDPDIAG(("*** UDP disconnected (res=%d, err=%d)\n",
1231 		   count, errno));
1232 	  warning("UDP link severed");
1233 	  printUdpInfo();
1234 	  closeUdpConn();
1235 	  commMode = commModeReq = COMM_TCP;
1236 	  commStatus = STAT_CONNECTED;
1237 	  if (udpWin)
1238 	    {
1239 	      udprefresh(UDP_STATUS);
1240 	      udprefresh(UDP_CURRENT);
1241 	    }
1242 	  return 0;
1243 	}
1244       printf("server disconnected\n");
1245       close(asock);
1246       serverDead = 1;
1247       return 0;
1248     }
1249   bufptr = buf;
1250   while (bufptr < buf + count)
1251     {
1252       /* this goto label for a bug w/ short packets */
1253     computesize:
1254       if (*bufptr < 1 ||
1255           *bufptr > NUM_PACKETS ||
1256           handlers[(unsigned char) *bufptr].size == 0) {
1257         int i;
1258 
1259         fprintf(stderr, "netrek protocol stream alignment failure, "
1260                 "next byte %d (0x%02x)\n", *bufptr, *bufptr);
1261 
1262         fprintf(stderr, "protocol buffer dump, bytes %d, [bufptr] at %d :\n",
1263                 count, (int) (bufptr - buf));
1264         for (i = 0; i < count; i++) {
1265           if (i == (bufptr - buf)) {
1266             fprintf(stderr, "[%02x]", (unsigned int) buf[i] & 0xff);
1267           } else {
1268             fprintf(stderr, " %02x ", (unsigned int) buf[i] & 0xff);
1269           }
1270         }
1271         fprintf(stderr, "\n");
1272         return 0;
1273       }
1274       size = handlers[(unsigned char) *bufptr].size;
1275 
1276 #ifdef SHORT_PACKETS
1277       if (size == -1)
1278 	{					 /* variable packet */
1279 	  size = getvpsize(bufptr);
1280 	  if (size <= 0)
1281 	    {
1282 	      fprintf(stderr, "Bad short-packet size value (%d)\n", size);
1283 	      return 0;
1284 	    }
1285 
1286 	  if (debug)
1287 	    printf("read variable packet size %d, type %d\n",
1288 		   size, *bufptr);
1289 	}
1290 #endif /* SHORT_PACKETS */
1291 
1292       if (size == 0)
1293 	fprintf(stderr, "Variable packet has 0 length! type=%d Trying to read more!\n", *bufptr);
1294       /* read broke in the middle of a packet, wait until we get the rest */
1295       while (size > count + (buf - bufptr) || size == 0)
1296 	{
1297 	  /* We wait for up to ten seconds for rest of packet. If we don't *
1298 	   * * get it, we assume the server died. */
1299 	  timeout.tv_sec = 20;
1300 	  timeout.tv_usec = 0;
1301 	  FD_ZERO(&readfds);
1302 	  FD_SET(asock, &readfds);
1303 	  /* readfds=1<<asock; */
1304 	  if ((temp = SELECT(max_fd, &readfds, 0, 0, &timeout)) == 0)
1305 	    {
1306 	      printf("Packet fragment.  Server must be dead\n");
1307 	      serverDead = 1;
1308 	      close(sock);
1309 	      return 0;
1310 	    }
1311 
1312 	  /* 88=largest short packet, messages */
1313 	  if (size == 0)
1314 	    {
1315 	      temp = read(asock, buf + count, 88);
1316 	    }
1317 	  else
1318 	    temp = read(asock, buf + count, size - (count + (buf - bufptr)));
1319 	  count += temp;
1320 	  if (temp <= 0)
1321 	    {
1322 	      printf("2) Got read() of %d.  Server is dead\n", temp);
1323 	      serverDead = 1;
1324 	      close(sock);
1325 	      return 0;
1326 	    }
1327 	  /* go back to the size computation, hopefully with the rest of the */
1328 	  /* aborted packet in the buffer. */
1329 	  if (size == 0)
1330 	    goto computesize;
1331 	}
1332       if (handlers[(unsigned char) *bufptr].handler != NULL)
1333 	{
1334 	  if (asock != udpSock ||
1335 	      (!drop_flag || *bufptr == SP_SEQUENCE || *bufptr == SP_SC_SEQUENCE))
1336 	    {
1337 	      if (debug)
1338 		printf("read packet %d\n", *bufptr);
1339 
1340 #ifdef RECORDGAME
1341 	      if (recordFile != NULL && ckRecordPacket(*bufptr))
1342 		{
1343 		  if (fwrite(bufptr, size, 1, recordFile) != 1)
1344 		    {
1345 		      perror("write: (recordFile)");
1346 		      fclose(recordFile);
1347 		      recordFile = NULL;
1348 		    }
1349 		}
1350 #endif
1351 
1352 #ifdef PACKET_LOG
1353 	      if (log_packets)
1354 		{
1355 		  Log_Packet((char) (*bufptr), size);
1356 		  print_packet(bufptr,size);
1357 		}
1358 #endif
1359 
1360 	      if (asock == udpSock)
1361 		packets_received++;
1362 
1363 	      (*(handlers[(unsigned char) *bufptr].handler)) (bufptr
1364 
1365 #ifdef CORRUPTED_PACKETS
1366 					      ,asock
1367 #endif
1368 
1369 		  );
1370 	    }
1371 	  else
1372 	    {
1373 	      if (debug)
1374 		{
1375 		  if (drop_flag)
1376 		    printf("%d bytes dropped.\n", size);
1377 		}
1378 	      UDPDIAG(("Ignored type %d\n", *bufptr));
1379 	    }
1380 	}
1381       else
1382 	{
1383 	  printf("Handler for packet %d not installed...\n", *bufptr);
1384 	}
1385 
1386       bufptr += size;
1387 
1388 #ifdef nodef
1389       if (bufptr > buf + BUFSIZ)
1390 	{
1391 	  MCOPY(buf + BUFSIZ, buf, BUFSIZ);
1392 	  if (count == BUFSIZ * 2)
1393 	    {
1394 	      FD_ZERO(&readfds);
1395 	      FD_SET(asock, &readfds);
1396 	      /* readfds = 1<<asock; */
1397 	      if ((temp = SELECT(max_fd, &readfds, 0, 0, &timeout)) > 0)
1398 		{
1399 		  temp = read(asock, buf + BUFSIZ, BUFSIZ);
1400 		  count = BUFSIZ + temp;
1401 		  if (temp <= 0)
1402 		    {
1403 		      printf("3) Got read() of %d.  Server is dead\n", temp);
1404 		      serverDead = 1;
1405 		      close(sock);
1406 		      return 0;
1407 		    }
1408 		}
1409 	      else
1410 		{
1411 		  count = BUFSIZ;
1412 		}
1413 	    }
1414 	  else
1415 	    {
1416 	      count -= BUFSIZ;
1417 	    }
1418 	  bufptr -= BUFSIZ;
1419 	}
1420 #endif
1421     }
1422   return 1;
1423 }
1424 
handleTorp(struct torp_spacket * packet)1425 void    handleTorp(struct torp_spacket *packet)
1426 {
1427   struct torp *thetorp;
1428 
1429 #ifdef CORRUPTED_PACKETS
1430   if (ntohs(packet->tnum) >= MAXPLAYER * MAXTORP)
1431     {
1432       fprintf(stderr, "handleTorp: bad index %d\n", ntohs(packet->tnum));
1433       return;
1434     }
1435 #endif
1436 
1437   weaponUpdate = 1;
1438   thetorp = &torps[ntohs(packet->tnum)];
1439 
1440   thetorp->t_x = ntohl(packet->x);
1441   thetorp->t_y = ntohl(packet->y);
1442   thetorp->t_dir = packet->dir;
1443   thetorp->t_updateFuse = MAX(2, TORP_UPDATE_FUSE * server_ups / 5);
1444 
1445 
1446 #ifdef ROTATERACE
1447   if (rotate)
1448     {
1449       rotate_coord(&thetorp->t_x, &thetorp->t_y, rotate_deg,
1450 		   GWIDTH / 2, GWIDTH / 2);
1451       rotate_dir(&thetorp->t_dir, rotate_deg);
1452     }
1453 #endif
1454 
1455   if (gather_stats) {
1456     /*STATS_SP_TORP:DIR,TNUM,X,Y*/
1457     fprintf(statsFile, "\nSTATS_SP_TORP:\t");
1458     fprintf(statsFile, "%d\t%u\t%u\t%u",
1459             ((struct torp_spacket *) packet)->dir,
1460             ntohs(((struct torp_spacket *) packet)->tnum),
1461             ntohl(((struct torp_spacket *) packet)->x),
1462             ntohl(((struct torp_spacket *) packet)->y));
1463   }
1464 }
1465 
handleTorpInfo(struct torp_info_spacket * packet)1466 void    handleTorpInfo(struct torp_info_spacket *packet)
1467 {
1468   struct torp *thetorp;
1469 
1470 #ifdef CORRUPTED_PACKETS
1471   if (ntohs(packet->tnum) >= MAXPLAYER * MAXTORP)
1472     {
1473       fprintf(stderr, "handleTorpInfo: bad index %d\n", ntohs(packet->tnum));
1474       return;
1475     }
1476 #endif
1477 
1478   weaponUpdate = 1;
1479   thetorp = &torps[ntohs(packet->tnum)];
1480   thetorp->t_updateFuse = MAX(2, TORP_UPDATE_FUSE * server_ups / 5);
1481 
1482   if (packet->status == TEXPLODE && thetorp->t_status == TFREE)
1483     {
1484       /* FAT: redundant explosion; don't update p_ntorp */
1485       /* printf("texplode ignored\n"); */
1486       return;
1487     }
1488 
1489   if (packet->status && thetorp->t_status == TFREE)
1490     {
1491       players[thetorp->t_owner].p_ntorp++;
1492 
1493 #ifdef nodef
1494       if (players[thetorp->t_owner].p_status == PEXPLODE)
1495 	fprintf(stderr, "TORP STARTED WHEN PLAYER EXPLODED\n");
1496 #endif
1497 
1498       /* BORG TEST */
1499 
1500 #ifdef BD
1501       if (bd)
1502 	bd_new_torp(ntohs(packet->tnum), thetorp);
1503 #endif
1504     }
1505   if (packet->status == TFREE && thetorp->t_status)
1506     {
1507       players[thetorp->t_owner].p_ntorp--;
1508     }
1509   thetorp->t_war = packet->war;
1510 
1511   if (packet->status != thetorp->t_status)
1512     {
1513       /* FAT: prevent explosion reset */
1514       thetorp->t_status = packet->status;
1515       if (thetorp->t_status == TEXPLODE)
1516 	{
1517 	  thetorp->t_fuse = NUMDETFRAMES * server_ups / 5;
1518 	}
1519     }
1520   if (gather_stats) {
1521     /*STATS_SP_TORP_INFO:WAR\tSTATUS\tTNUM*/
1522     fprintf(statsFile, "\nSTATS_SP_TORP_INFO:\t");
1523     fprintf(statsFile, "%d\t%d\t%u",
1524             ((struct torp_info_spacket *) packet)->war,
1525             ((struct torp_info_spacket *) packet)->status,
1526             ntohs(((struct torp_info_spacket *) packet)->tnum));
1527   }
1528 }
1529 
handleStatus(struct status_spacket * packet)1530 void    handleStatus(struct status_spacket *packet)
1531 {
1532   status->tourn = packet->tourn;
1533   status->armsbomb = ntohl(packet->armsbomb);
1534   status->planets = ntohl(packet->planets);
1535   status->kills = ntohl(packet->kills);
1536   status->losses = ntohl(packet->losses);
1537   status->time = ntohl(packet->time);
1538   status->timeprod = ntohl(packet->timeprod);
1539 
1540   if (debug)
1541     {
1542       printf("SERVER STATS:\n");
1543       printf("time: %d\n", status->time / (60 * 60 * 10));
1544       printf("kills: %d\n", status->kills);
1545       printf("losses: %d\n", status->losses);
1546       printf("planets: %d\n", status->planets);
1547       printf("armsbomb: %d\n", status->armsbomb);
1548     }
1549 
1550   if (gather_stats) {
1551     /*STATS_SP_STATUS:\tTOURN\tARMSBOMB\tPLANETS\tKILLS\tLOSSES\tTIME\tTIMEPROD*/
1552     fprintf(statsFile, "\nSTATS_SP_STATUS:\t");
1553     fprintf(statsFile, "\t%d\t%u\t%u\t%u\t%u\t%u\t%u",
1554             ((struct status_spacket *) packet)->tourn,
1555             ntohl(((struct status_spacket *) packet)->armsbomb),
1556             ntohl(((struct status_spacket *) packet)->planets),
1557             ntohl(((struct status_spacket *) packet)->kills),
1558             ntohl(((struct status_spacket *) packet)->losses),
1559             ntohl(((struct status_spacket *) packet)->time),
1560             ntohl(((struct status_spacket *) packet)->timeprod));
1561   }
1562 }
1563 
become(struct player * pl)1564 void become(struct player *pl)
1565 {
1566   int p_no;
1567 
1568   p_no = pl->p_no;
1569   memcpy(&pl->p_ship, &me->p_ship, sizeof(struct ship));
1570   memcpy(&pl->p_stats, &me->p_stats, sizeof(struct stats));
1571   memcpy(pl, me, sizeof(struct player));
1572   pl->p_no = p_no;
1573   me->p_status = PFREE;
1574 }
1575 
handleSelf(struct you_spacket * packet)1576 void    handleSelf(struct you_spacket *packet) /* SP_YOU */
1577 {
1578   struct player* pl;
1579   static int seen = 0;
1580 
1581   pl = &players[(unsigned char) packet->pnum];
1582 
1583 #ifdef CORRUPTED_PACKETS
1584   if (packet->pnum < 0 || packet->pnum >= MAXPLAYER)
1585     {
1586       fprintf(stderr, "handleSelf: bad index %d\n", packet->pnum);
1587       return;
1588     }
1589 #endif
1590   if (seen && packet->pnum != me->p_no) become(pl);
1591   seen++;
1592 
1593   if (!F_many_self)
1594     {
1595       me = (ghoststart ? &players[ghost_pno] : pl);
1596       myship = &(me->p_ship);
1597       mystats = &(me->p_stats);
1598     }
1599 
1600 #ifdef PLIST2
1601   if (pl->p_hostile != packet->hostile)
1602     {
1603       pl->p_hostile = packet->hostile;
1604       PlistNoteHostile(packet->pnum);
1605     }
1606 #else
1607   pl->p_hostile = packet->hostile;
1608 #endif
1609 
1610   pl->p_swar = packet->swar;
1611   pl->p_armies = packet->armies;
1612 
1613 #ifdef nodef
1614   if (((pl->p_flags & PFGREEN) && (ntohl(packet->flags) & PFRED)) ||
1615       ((pl->p_flags & PFRED) && (ntohl(packet->flags) & PFGREEN)))
1616     printf("green/red transition\n");
1617 #endif
1618 
1619   pl->p_flags = ntohl(packet->flags);
1620   if (pl->p_flags & PFPLOCK)
1621     {
1622       redrawPlayer[pl->p_playerl] = 1;
1623     }
1624   pl->p_damage = ntohl(packet->damage);
1625   pl->p_shield = ntohl(packet->shield);
1626   pl->p_fuel = ntohl(packet->fuel);
1627   pl->p_etemp = ntohs(packet->etemp);
1628   pl->p_wtemp = ntohs(packet->wtemp);
1629   pl->p_whydead = ntohs(packet->whydead);
1630   pl->p_whodead = ntohs(packet->whodead);
1631 
1632 #ifdef INCLUDE_VISTRACT
1633   if (packet->tractor & 0x40) {
1634     pl->p_tractor = (short) packet->tractor & (~0x40);	/* ATM - visible
1635 							 * tractors */
1636   }
1637 
1638 #ifdef nodef					 /* tmp */
1639   else
1640     pl->p_tractor = -1;
1641 #endif /* nodef */
1642 
1643 #endif
1644 }
1645 
1646 
handlePlayer(struct player_spacket * packet)1647 void    handlePlayer(struct player_spacket *packet)
1648 {
1649   register struct player *pl;
1650   int     x, y;
1651 
1652 #ifdef CORRUPTED_PACKETS
1653   if (packet->pnum >= MAXPLAYER)
1654     {
1655       fprintf(stderr, "handlePlayer: bad index %d\n", packet->pnum);
1656       return;
1657     }
1658 #endif
1659 
1660 
1661   pl = &players[(unsigned char) packet->pnum];
1662 
1663   pl->p_dir = packet->dir;
1664   pl->p_speed = packet->speed;
1665   PlistNoteSpeed(packet->pnum);
1666 
1667   if (F_cloak_maxwarp && pl != me)
1668     {
1669       if (pl->p_speed == 0xf)
1670 	pl->p_flags |= PFCLOAK;
1671       else if (pl->p_flags & PFCLOAK)
1672 	pl->p_flags &= ~PFCLOAK;
1673     }
1674   x = ntohl(packet->x);
1675   y = ntohl(packet->y);
1676 
1677 #ifdef WARP_DEAD
1678   if (F_dead_warp && pl->p_speed == 14 && x == -10000 && y == -10000 && (pl->p_status != PEXPLODE))
1679     {
1680       pl->p_status = PEXPLODE;
1681       x = pl->p_x;
1682       y = pl->p_y;
1683       if (pl->p_dir > DEADPACKETS)
1684 	pl->p_explode = EX_FRAMES;
1685       else
1686 	pl->p_explode = 0;
1687       redrawPlayer[packet->pnum] = 1;
1688       PlistNoteUpdate(packet->pnum);
1689     }
1690 #endif
1691 
1692   pl->p_x = x;
1693   pl->p_y = y;
1694 
1695   redrawPlayer[(unsigned char) packet->pnum] = 1;
1696 
1697   if (me == pl)
1698     {
1699       extern int my_x, my_y;			 /* From short.c */
1700 
1701       my_x = x;
1702       my_y = y;
1703     }
1704 
1705 
1706 #ifdef ROTATERACE
1707   if (rotate)
1708     {
1709       rotate_coord(&pl->p_x, &pl->p_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
1710       rotate_dir(&pl->p_dir, rotate_deg);
1711     }
1712 #endif
1713 
1714   if (gather_stats) {
1715     /* SP_PLAYER:PNUN,DIR,SPEED,X,Y */
1716     fprintf(statsFile, "\nSTATS_SP_PLAYER:\t");
1717     fprintf(statsFile, "%d\t%u\t%d\t%d\t%d",
1718             ((struct player_spacket *) packet)->pnum,
1719             ((struct player_spacket *) packet)->dir,
1720             ((struct player_spacket *) packet)->speed,
1721             ntohl(((struct player_spacket *) packet)->x),
1722             ntohl(((struct player_spacket *) packet)->y));
1723   }
1724 }
1725 
1726 
handleWarning(struct warning_spacket * packet)1727 void    handleWarning(struct warning_spacket *packet)
1728 {
1729   packet->mesg[sizeof(packet->mesg) - 1] = '\0'; /* guarantee null * *
1730 						  * termination */
1731   warning(packet->mesg);
1732 }
1733 
sendShortPacket(char type,char state)1734 void sendShortPacket(char type, char state)
1735 {
1736   struct speed_cpacket speedReq;
1737 
1738   bzero(&speedReq, sizeof(speedReq));
1739   speedReq.type = type;
1740   speedReq.speed = state;
1741   sendServerPacket((struct player_spacket *) &speedReq);
1742 
1743   /* if we're sending in UDP mode, be prepared to force it */
1744   if (commMode == COMM_UDP && udpClientSend >= 2)
1745     {
1746       switch (type)
1747 	{
1748 	case CP_SPEED:
1749 	  fSpeed = state | 0x100;
1750 	  break;
1751 	case CP_DIRECTION:
1752 	  fDirection = state | 0x100;
1753 	  break;
1754 	case CP_SHIELD:
1755 	  fShield = state | 0xa00;
1756 	  break;
1757 	case CP_ORBIT:
1758 	  fOrbit = state | 0xa00;
1759 	  break;
1760 	case CP_REPAIR:
1761 	  fRepair = state | 0xa00;
1762 	  break;
1763 	case CP_CLOAK:
1764 	  fCloak = state | 0xa00;
1765 	  break;
1766 	case CP_BOMB:
1767 	  fBomb = state | 0xa00;
1768 	  break;
1769 	case CP_DOCKPERM:
1770 	  fDockperm = state | 0xa00;
1771 	  break;
1772 	case CP_PLAYLOCK:
1773 	  fPlayLock = state | 0xa00;
1774 	  break;
1775 	case CP_PLANLOCK:
1776 	  fPlanLock = state | 0xa00;
1777 	  break;
1778 	case CP_BEAM:
1779 	  if (state == 1)
1780 	    fBeamup = 1 | 0x500;
1781 	  else
1782 	    fBeamdown = 2 | 0x500;
1783 	  break;
1784 	}
1785 
1786       /* force weapons too? */
1787       if (udpClientSend >= 3)
1788 	{
1789 	  switch (type)
1790 	    {
1791 	    case CP_PHASER:
1792 	      fPhaser = state | 0x100;
1793 	      break;
1794 	    case CP_PLASMA:
1795 	      fPlasma = state | 0x100;
1796 	      break;
1797 	    }
1798 	}
1799     }
1800 }
1801 
sendServerPacket(void * buffer)1802 void sendServerPacket(void *buffer)
1803 {
1804   int     size;
1805   struct player_spacket *packet = (struct player_spacket *) buffer;
1806 
1807   if (serverDead)
1808     return;
1809   if (packet->type < 1 ||
1810       packet->type > NUM_SIZES ||
1811       sizes[(unsigned char) packet->type] == 0)
1812     {
1813       printf("Attempt to send strange packet %d!\n", packet->type);
1814       return;
1815     }
1816   size = sizes[(unsigned char) packet->type];
1817 
1818 #ifdef PACKET_LOG
1819   if (log_packets)
1820     {
1821       Log_OPacket(packet->type, size);
1822       print_opacket((char *) packet,size);
1823     }
1824 #endif
1825 
1826   if (commMode == COMM_UDP)
1827     {
1828       /* for now, just sent everything via TCP */
1829     }
1830   if (commMode == COMM_TCP || !udpClientSend)
1831     {
1832       /* special case for verify packet */
1833       if (packet->type == CP_UDP_REQ)
1834 	{
1835 	  if (((struct udp_req_cpacket *) packet)->request == COMM_VERIFY)
1836 	    goto send_udp;
1837 	}
1838       /* business as usual (or player has turned off UDP transmission) */
1839       if (gwrite(sock, (char *) packet, size) != size)
1840 	{
1841 	  printf("gwrite failed.  Server must be dead\n");
1842 	  serverDead = 1;
1843 	}
1844     }
1845   else
1846     {
1847       /* UDP stuff */
1848       switch (packet->type)
1849 	{
1850 	case CP_SPEED:
1851 	case CP_DIRECTION:
1852 	case CP_PHASER:
1853 	case CP_PLASMA:
1854 	case CP_TORP:
1855 	case CP_QUIT:
1856 	case CP_PRACTR:
1857 	case CP_SHIELD:
1858 	case CP_REPAIR:
1859 	case CP_ORBIT:
1860 	case CP_PLANLOCK:
1861 	case CP_PLAYLOCK:
1862 	case CP_BOMB:
1863 	case CP_BEAM:
1864 	case CP_CLOAK:
1865 	case CP_DET_TORPS:
1866 	case CP_DET_MYTORP:
1867 	case CP_REFIT:
1868 	case CP_TRACTOR:
1869 	case CP_REPRESS:
1870 	case CP_COUP:
1871 	case CP_DOCKPERM:
1872 
1873 #ifdef INCLUDE_SCAN
1874 	case CP_SCAN:
1875 #endif
1876 
1877 	case CP_PING_RESPONSE:
1878 	  /* non-critical stuff, use UDP */
1879 	send_udp:
1880 	  packets_sent++;
1881 
1882 	  V_UDPDIAG(("Sent %d on UDP port\n", packet->type));
1883 	  if (gwrite(udpSock, (char *) packet, size) != size)
1884 	    {
1885 	      UDPDIAG(("gwrite on UDP failed.  Closing UDP connection\n"));
1886 	      warning("UDP link severed");
1887 	      /* serverDead=1; */
1888 	      commModeReq = commMode = COMM_TCP;
1889 	      commStatus = STAT_CONNECTED;
1890 	      commSwitchTimeout = 0;
1891 	      if (udpWin)
1892 		{
1893 		  udprefresh(UDP_STATUS);
1894 		  udprefresh(UDP_CURRENT);
1895 		}
1896 	      if (udpSock >= 0)
1897 		closeUdpConn();
1898 	    }
1899 	  break;
1900 
1901 	default:
1902 	  /* critical stuff, use TCP */
1903 	  if (gwrite(sock, (char *) packet, size) != size)
1904 	    {
1905 	      printf("gwrite failed.  Server must be dead\n");
1906 	      serverDead = 1;
1907 	    }
1908 	}
1909     }
1910 }
1911 
handlePlanet(struct planet_spacket * packet)1912 void    handlePlanet(struct planet_spacket *packet)
1913 {
1914   struct planet *plan;
1915 
1916   /* FAT: prevent excessive redraw */
1917   int     redraw = 0;
1918 
1919 #ifdef CORRUPTED_PACKETS
1920   if (packet->pnum >= MAXPLANETS)
1921     {
1922       fprintf(stderr, "handlePlanet: bad index %d\n", packet->pnum);
1923       return;
1924     }
1925 #endif
1926 
1927   plan = &planets[(unsigned char) packet->pnum];
1928 
1929 #ifdef nodef
1930   monpoprate(plan, packet);
1931 #endif
1932 
1933   if (plan->pl_owner != packet->owner)
1934     redraw = 1;
1935   plan->pl_owner = packet->owner;
1936   if (plan->pl_owner < FED || plan->pl_owner > ORI)
1937     plan->pl_owner = NOBODY;
1938   if (plan->pl_info != packet->info)
1939     redraw = 1;
1940   plan->pl_info = packet->info;
1941   /* Redraw the planet because it was updated by server */
1942 
1943   if (plan->pl_flags != (int) ntohs(packet->flags))
1944     redraw = 1;
1945   plan->pl_flags = (int) ntohs(packet->flags);
1946 
1947   if (plan->pl_armies != ntohl(packet->armies))
1948     {
1949       /* don't redraw when armies change unless it crosses the '4' army
1950        * limit. Keeps people from watching for planet 'flicker' when
1951        * players are beaming */
1952       int     planetarmies = ntohl(packet->armies);
1953 
1954       if ((plan->pl_armies < 5 && planetarmies > 4) ||
1955 	  (plan->pl_armies > 4 && planetarmies < 5))
1956 	redraw = 1;
1957     }
1958   plan->pl_armies = ntohl(packet->armies);
1959 
1960 #ifndef RECORDGAME
1961   if (plan->pl_info == 0)
1962     {
1963       plan->pl_owner = NOBODY;
1964     }
1965 #endif
1966 
1967   if (redraw)
1968     {
1969       plan->pl_flags |= PLREDRAW;
1970     }
1971 }
1972 
handlePhaser(struct phaser_spacket * packet)1973 void    handlePhaser(struct phaser_spacket *packet)
1974 {
1975   struct phaser *phas;
1976 
1977 #ifdef CORRUPTED_PACKETS
1978   if (packet->pnum >= MAXPLAYER)
1979     {
1980       fprintf(stderr, "handlePhaser: bad index %d\n", packet->pnum);
1981       return;
1982     }
1983   if (packet->status == PHHIT &&
1984       (ntohl(packet->target) < 0 || ntohl(packet->target) >= MAXPLAYER))
1985     {
1986       fprintf(stderr, "handlePhaser: bad target %d\n", ntohl(packet->target));
1987       return;
1988     }
1989 #endif
1990 
1991   weaponUpdate = 1;
1992   phas = &phasers[(unsigned char) packet->pnum];
1993   phas->ph_status = packet->status;
1994   phas->ph_dir = packet->dir;
1995   phas->ph_x = ntohl(packet->x);
1996   phas->ph_y = ntohl(packet->y);
1997   phas->ph_target = ntohl(packet->target);
1998   phas->ph_fuse = 0;
1999 #ifdef SOUND
2000   phas->sound_phaser = 1;
2001 #endif
2002   phas->ph_updateFuse = PHASER_UPDATE_FUSE * server_ups / 10;
2003 
2004 #ifdef ROTATERACE
2005   if (rotate)
2006     {
2007       rotate_coord(&phas->ph_x, &phas->ph_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
2008       rotate_dir(&phas->ph_dir, rotate_deg);
2009     }
2010 #endif
2011 
2012   if (gather_stats) {
2013     /* not getting any data?*/
2014     /*STATS_SP_PHASER:\tpnum\tstats\tdir\tx\ty\ttarget*/
2015     fprintf(statsFile, "\nSTATS_SP_PHASER\t");
2016     fprintf(statsFile, "%d\t%d\t%u\t%d\t%d\t%d",
2017             ((struct phaser_spacket *) packet)->pnum,
2018             ((struct phaser_spacket *) packet)->status,
2019             ((struct phaser_spacket *) packet)->dir,
2020             ntohl(((struct phaser_spacket *) packet)->x),
2021             ntohl(((struct phaser_spacket *) packet)->y),
2022             ntohl(((struct phaser_spacket *) packet)->target));
2023   }
2024 }
2025 
handleMessage(struct mesg_spacket * packet)2026 void    handleMessage(struct mesg_spacket *packet)
2027 {
2028   if (packet->m_from >= MAXPLAYER)
2029     packet->m_from = 255;
2030 
2031 #ifdef CORRUPTED_PACKETS
2032   packet->mesg[sizeof(packet->mesg) - 1] = '\0';
2033 #endif
2034 
2035   /* printf("flags: 0x%x\n", packet->m_flags);
2036    * printf("from: %d\n", packet->m_from);
2037    * printf("recpt: %d\n", packet->m_recpt);
2038    * printf("mesg: %s\n", packet->mesg);
2039    */
2040 
2041   dmessage(packet->mesg, packet->m_flags, packet->m_from, packet->m_recpt);
2042 
2043   if (gather_stats) {
2044     /*STATS_SP_MESSAGE:\tFLAGS\tRECPT\tFROM\tMESG*/
2045     fprintf(statsFile, "\nSTATS_SP_MESSAGE:\t");
2046     fprintf(statsFile, "0x%0X\t%d\t%d\t%s",
2047             ((struct mesg_spacket *) packet)->m_flags,
2048             ((struct mesg_spacket *) packet)->m_recpt,
2049             ((struct mesg_spacket *) packet)->m_from,
2050             ((struct mesg_spacket *) packet)->mesg);
2051   }
2052 }
2053 
handleQueue(struct queue_spacket * packet)2054 void    handleQueue(struct queue_spacket *packet)
2055 {
2056   queuePos = ntohs(packet->pos);
2057 }
2058 
sendTeamReq(int team,int ship)2059 void sendTeamReq(int team, int ship)
2060 {
2061   struct outfit_cpacket outfitReq;
2062 
2063   bzero(&outfitReq, sizeof(outfitReq));
2064   outfitReq.type = CP_OUTFIT;
2065   outfitReq.team = team;
2066   outfitReq.ship = ship;
2067   sendServerPacket(&outfitReq);
2068 }
2069 
handlePickok(struct pickok_spacket * packet)2070 void    handlePickok(struct pickok_spacket *packet)
2071 {
2072   pickOk = packet->state;
2073 }
2074 
sendLoginReq(char * name,char * pass,char * login,char query)2075 void sendLoginReq(char *name, char *pass, char *login, char query)
2076 {
2077   struct login_cpacket packet;
2078 
2079   bzero(&packet, sizeof(packet));
2080   strcpy(packet.name, name);
2081   strcpy(packet.password, pass);
2082   if (strlen(login) > 15)
2083     login[15] = 0;
2084   strcpy(packet.login, login);
2085   packet.type = CP_LOGIN;
2086   packet.query = query;
2087   sendServerPacket((struct player_spacket *) &packet);
2088 }
2089 
handleLogin(struct login_spacket * packet)2090 void    handleLogin(struct login_spacket *packet)
2091 {
2092   loginAccept = packet->accept;
2093   if (packet->accept)
2094     {
2095       /* no longer needed .. we have it in xtrekrc bcopy(packet->keymap,
2096        * mystats->st_keymap, 96); */
2097       mystats->st_flags = ntohl(packet->flags);
2098 
2099 #ifdef nodef
2100       namemode = (me->p_stats.st_flags / ST_NAMEMODE) & 1;
2101       keeppeace = (me->p_stats.st_flags / ST_KEEPPEACE) & 1;
2102       showlocal = (me->p_stats.st_flags / ST_SHOWLOCAL) & 3;
2103       showgalactic = (me->p_stats.st_flags / ST_SHOWGLOBAL) & 3;
2104 #endif
2105     }
2106 }
2107 
sendTractorReq(char state,char pnum)2108 void sendTractorReq(char state, char pnum)
2109 {
2110   struct tractor_cpacket tractorReq;
2111 
2112   memset(&tractorReq, 0, sizeof(struct tractor_cpacket));
2113   tractorReq.type = CP_TRACTOR;
2114   tractorReq.state = state;
2115   tractorReq.pnum = pnum;
2116   sendServerPacket((struct player_spacket *) &tractorReq);
2117 
2118   if (state)
2119     fTractor = pnum | 0x40;
2120   else
2121     fTractor = 0;
2122 }
2123 
sendRepressReq(char state,char pnum)2124 void sendRepressReq(char state, char pnum)
2125 {
2126   struct repress_cpacket repressReq;
2127 
2128   memset(&repressReq, 0, sizeof(struct repress_cpacket));
2129   repressReq.type = CP_REPRESS;
2130   repressReq.state = state;
2131   repressReq.pnum = pnum;
2132   sendServerPacket((struct player_spacket *) &repressReq);
2133 
2134   if (state)
2135     fRepress = pnum | 0x40;
2136   else
2137     fRepress = 0;
2138 }
2139 
sendDetMineReq(short int torp)2140 void sendDetMineReq(short int torp)
2141 {
2142   struct det_mytorp_cpacket detReq;
2143 
2144   memset(&detReq, 0, sizeof(struct det_mytorp_cpacket));
2145   detReq.type = CP_DET_MYTORP;
2146   detReq.tnum = htons(torp);
2147   sendServerPacket((struct player_spacket *) &detReq);
2148 }
2149 
handlePlasmaInfo(struct plasma_info_spacket * packet)2150 void    handlePlasmaInfo(struct plasma_info_spacket *packet)
2151 {
2152   struct plasmatorp *thetorp;
2153 
2154 #ifdef CORRUPTED_PACKETS
2155   if (ntohs(packet->pnum) >= MAXPLAYER * MAXPLASMA)
2156     {
2157       fprintf(stderr, "handlePlasmaInfo: bad index %d\n", packet->pnum);
2158       return;
2159     }
2160 #endif
2161 
2162   weaponUpdate = 1;
2163   thetorp = &plasmatorps[ntohs(packet->pnum)];
2164   thetorp->pt_updateFuse = MAX(2, PLASMA_UPDATE_FUSE * server_ups / 5);
2165   if (packet->status == PTEXPLODE && thetorp->pt_status == PTFREE)
2166     {
2167       /* FAT: redundant explosion; don't update p_nplasmatorp */
2168       return;
2169     }
2170   if (!thetorp->pt_status && packet->status)
2171     {
2172       players[thetorp->pt_owner].p_nplasmatorp++;
2173     }
2174   if (thetorp->pt_status && !packet->status)
2175     {
2176       players[thetorp->pt_owner].p_nplasmatorp--;
2177     }
2178   thetorp->pt_war = packet->war;
2179   if (thetorp->pt_status != packet->status)
2180     {
2181       /* FAT: prevent explosion timer from being reset */
2182       thetorp->pt_status = packet->status;
2183       if (thetorp->pt_status == PTEXPLODE)
2184 	{
2185 	  thetorp->pt_fuse = NUMDETFRAMES * server_ups / 5;
2186 	}
2187     }
2188 
2189   if (gather_stats) {
2190     /*STATS_SP_PLASMA_INFO:\tWAR\tSTATUS\tPNUM*/
2191     fprintf(statsFile, "\nSTATS_SP_PLASMA_INFO:\t");
2192     fprintf(statsFile, "%d\t%d\t%u",
2193             ((struct plasma_info_spacket *) packet)->war,
2194             ((struct plasma_info_spacket *) packet)->status,
2195             ntohs(((struct plasma_info_spacket *) packet)->pnum));
2196   }
2197 }
2198 
handlePlasma(struct plasma_spacket * packet)2199 void    handlePlasma(struct plasma_spacket *packet)
2200 {
2201   struct plasmatorp *thetorp;
2202 
2203 #ifdef CORRUPTED_PACKETS
2204   if (ntohs(packet->pnum) >= MAXPLAYER * MAXPLASMA)
2205     {
2206       fprintf(stderr, "handlePlasma: bad index %d\n", packet->pnum);
2207       return;
2208     }
2209 #endif
2210 
2211   weaponUpdate = 1;
2212   thetorp = &plasmatorps[ntohs(packet->pnum)];
2213   thetorp->pt_x = ntohl(packet->x);
2214   thetorp->pt_y = ntohl(packet->y);
2215   thetorp->pt_updateFuse = MAX(2, PLASMA_UPDATE_FUSE * server_ups / 5);
2216 
2217 #ifdef ROTATERACE
2218   if (rotate)
2219     {
2220       rotate_coord(&thetorp->pt_x, &thetorp->pt_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
2221     }
2222 #endif
2223 
2224   if (gather_stats) {
2225     /*STATS_SP_PLASMA:\tPNUM\tX\tY*/
2226     fprintf(statsFile, "\nSTATS_SP_PLASMA:\t%u\t%d\t%d",
2227             ntohs(((struct plasma_spacket *) packet)->pnum),
2228             ntohl(((struct plasma_spacket *) packet)->x),
2229             ntohl(((struct plasma_spacket *) packet)->y));
2230   }
2231 }
2232 
handleFlags(struct flags_spacket * packet)2233 void    handleFlags(struct flags_spacket *packet)
2234 {
2235   struct player* pl;
2236 
2237   pl = &players[(unsigned char) packet->pnum];
2238 
2239 #ifdef CORRUPTED_PACKETS
2240   if (packet->pnum >= MAXPLAYER)
2241     {
2242       fprintf(stderr, "handleFlags: bad index %d\n", packet->pnum);
2243       return;
2244     }
2245 #endif
2246 
2247   if (pl->p_flags != ntohl(packet->flags)
2248 
2249 #ifdef INCLUDE_VISTRACT
2250       || pl->p_tractor != ((short) packet->tractor & (~0x40))
2251 #endif
2252 
2253       )
2254     {
2255       /* FAT: prevent redundant player update */
2256       redrawPlayer[(unsigned char) packet->pnum] = 1;
2257     }
2258   else
2259     return;
2260 
2261   pl->p_flags = ntohl(packet->flags);
2262 
2263 #ifdef INCLUDE_VISTRACT
2264   if (packet->tractor & 0x40) {
2265     pl->p_tractor =
2266       (short) packet->tractor & (~0x40); /* ATM visible tractors */
2267   } else
2268 #endif /* INCLUDE_VISTRACT */
2269 
2270     pl->p_tractor = -1;
2271 }
2272 
handleKills(struct kills_spacket * packet)2273 void    handleKills(struct kills_spacket *packet)
2274 {
2275 
2276 #ifdef CORRUPTED_PACKETS
2277   if (packet->pnum >= MAXPLAYER)
2278     {
2279       fprintf(stderr, "handleKills: bad index %d\n", packet->pnum);
2280       return;
2281     }
2282 #endif
2283 
2284   if (players[(unsigned char) packet->pnum].p_kills !=
2285       ntohl(packet->kills) / 100.0)
2286     {
2287       players[(unsigned char) packet->pnum].p_kills =
2288         ntohl(packet->kills) / 100.0;
2289       /* FAT: prevent redundant player update */
2290       PlistNoteUpdate((unsigned char) packet->pnum);
2291 
2292 #ifdef ARMY_SLIDER
2293       if (me == &players[(unsigned char) packet->pnum])
2294 	{
2295 	  calibrate_stats();
2296 	  redrawStats();
2297 	}
2298 #endif /* ARMY_SLIDER */
2299     }
2300 
2301   if (gather_stats) {
2302     /*STATS_SP_KILLS:\tPNUM\tKILLS*/
2303     fprintf(statsFile, "\nSTATS_SP_KILLS:\t");
2304     fprintf(statsFile, "%d\t%u",
2305             ((struct kills_spacket *) packet)->pnum,
2306             ntohl(((struct kills_spacket *) packet)->kills));
2307   }
2308 }
2309 
handlePStatus(struct pstatus_spacket * packet)2310 void    handlePStatus(struct pstatus_spacket *packet)
2311 {
2312   register struct player *j;
2313 
2314 #ifdef CORRUPTED_PACKETS
2315   if (packet->pnum >= MAXPLAYER)
2316     {
2317       fprintf(stderr, "handlePStatus: bad index %d\n", packet->pnum);
2318       return;
2319     }
2320 #endif
2321 
2322   j = &players[(unsigned char) packet->pnum];
2323 
2324   if (packet->status == j->p_status)
2325     return;
2326 
2327   if (packet->status == PEXPLODE)
2328     {
2329       j->p_explode = 0;
2330     }
2331 
2332   /* Ignore DEAD status. Instead, we treat it as PEXPLODE. This gives us time
2333    * * * to animate all the frames necessary for the explosions at our own
2334    * pace.  */
2335   else if (packet->status == PDEAD)
2336     {
2337       packet->status = PEXPLODE;
2338 
2339       if (j->p_status == PEXPLODE)		 /* Prevent redundant updates
2340 						  *
2341 						  */
2342 	return;
2343     }
2344 
2345   /* guarantees we won't miss the kill message since this is TCP */
2346   else if (packet->status == PALIVE && j->p_status != PALIVE)
2347     j->p_kills = 0.;
2348 
2349   /* update the player list, especially if this signals a new arrival */
2350   PlistNoteUpdate((unsigned char) packet->pnum);
2351   if (j->p_status == PFREE || packet->status == PFREE)
2352     PlistNoteArrive(packet->pnum);
2353 
2354   j->p_status = packet->status;
2355   redrawPlayer[(unsigned char) packet->pnum] = 1;
2356 }
2357 
handleMotd(struct motd_spacket * packet)2358 void    handleMotd(struct motd_spacket *packet)
2359 {
2360   packet->line[sizeof(packet->line) - 1] = '\0';
2361   newMotdLine(packet->line);
2362 }
2363 
sendMessage(char * mes,int group,int indiv)2364 void sendMessage(char *mes, int group, int indiv)
2365 {
2366   struct mesg_cpacket mesPacket;
2367 
2368   bzero(&mesPacket, sizeof(mesPacket));
2369 #ifdef SHORT_PACKETS
2370   if (recv_short)
2371     {
2372       int     size;
2373 
2374       size = strlen(mes);
2375       size += 5;				 /* 1 for '\0', 4 * *
2376 						  * packetheader */
2377       if ((size % 4) != 0)
2378 	size += (4 - (size % 4));
2379       mesPacket.pad1 = (char) size;
2380       sizes[CP_S_MESSAGE] = size;
2381       mesPacket.type = CP_S_MESSAGE;
2382     }
2383   else
2384 #endif
2385 
2386     mesPacket.type = CP_MESSAGE;
2387   mesPacket.group = group;
2388   mesPacket.indiv = indiv;
2389   STRNCPY(mesPacket.mesg, mes, 80);
2390   sendServerPacket((struct player_spacket *) &mesPacket);
2391 }
2392 
2393 
handleMask(struct mask_spacket * packet)2394 void    handleMask(struct mask_spacket *packet)
2395 {
2396   motd_refresh();
2397   tournMask = packet->mask;
2398 }
2399 
sendOptionsPacket(void)2400 void sendOptionsPacket(void)
2401 {
2402   struct options_cpacket optPacket;
2403 
2404   bzero(&optPacket, sizeof(optPacket));
2405   optPacket.type = CP_OPTIONS;
2406   optPacket.flags =
2407       htonl(ST_MAPMODE +			 /* always on */
2408 	    ST_NAMEMODE * namemode +
2409 	    ST_SHOWSHIELDS +			 /* always on */
2410 	    ST_KEEPPEACE * keeppeace +
2411 	    ST_SHOWLOCAL * showlocal +
2412 	    ST_SHOWGLOBAL * showgalactic);
2413   MCOPY(mystats->st_keymap, optPacket.keymap, 96);
2414   sendServerPacket((struct player_spacket *) &optPacket);
2415 }
2416 
pickSocket(int old)2417 static void pickSocket(int old)
2418 {
2419   int     newsocket;
2420   struct socket_cpacket sockPack;
2421 
2422   /* If baseLocalPort is defined we want to start from that */
2423   if(baseLocalPort)
2424       newsocket = baseLocalPort;
2425   else
2426       newsocket = (getpid() & 32767);
2427   while (newsocket < 2048 || newsocket == old)
2428     {
2429       if(baseLocalPort)
2430           newsocket++;
2431       else
2432           newsocket = (newsocket + 10687) & 32767;
2433     }
2434   bzero(&sockPack,sizeof(sockPack));
2435   sockPack.type = CP_SOCKET;
2436   sockPack.socket = htonl(newsocket);
2437   sockPack.version = (char) SOCKVERSION;
2438   sockPack.udp_version = (char) UDPVERSION;
2439   sendServerPacket((struct player_spacket *) &sockPack);
2440   /* Did we get new socket # sent? */
2441   if (serverDead)
2442     return;
2443   nextSocket = newsocket;
2444 }
2445 
2446 static void
handleBadVersionSorry(char * reason)2447 handleBadVersionSorry (char *reason)
2448 {
2449     printf("%s\nTry again later.\n", reason);
2450 }
2451 
handleBadVersion(struct badversion_spacket * packet)2452 void    handleBadVersion(struct badversion_spacket *packet)
2453 {
2454   int badversion = packet->why;
2455 
2456   if (badversion >= 0 && badversion <= MAXBADVERSION) {
2457     handleBadVersionSorry(badversion_long_strings[badversion]);
2458   }
2459   terminate(EXIT_BADVERSION_BASE+badversion);
2460 }
2461 
gwrite(int fd,char * buf,register int bytes)2462 int gwrite(int fd, char *buf, register int bytes)
2463 {
2464   LONG    orig = bytes;
2465   register LONG n;
2466 
2467   while (bytes)
2468     {
2469       n = write(fd, buf, bytes);
2470       if (n < 0)
2471 	{
2472 	  if (fd == udpSock)
2473 	    {
2474 	      fprintf(stderr, "Tried to write %d, %d\n", fd, bytes);
2475 	      perror("write");
2476 	      printUdpInfo();
2477 	    }
2478 	  return -1;
2479 	}
2480       bytes -= n;
2481       buf += n;
2482     }
2483   return orig;
2484 }
2485 
handleHostile(struct hostile_spacket * packet)2486 void    handleHostile(struct hostile_spacket *packet)
2487 {
2488   int p_no = packet->pnum;
2489   struct player *pl;
2490 
2491 #ifdef CORRUPTED_PACKETS
2492   if (p_no < 0 || p_no >= MAXPLAYER)
2493     {
2494       fprintf(stderr, "handleHostile: bad index %d\n", p_no);
2495       return;
2496     }
2497 #endif
2498 
2499   pl = &players[p_no];
2500   if (pl->p_swar != packet->war ||
2501       pl->p_hostile != packet->hostile)
2502     {
2503       /* FAT: prevent redundant player update & redraw */
2504       pl->p_swar = packet->war;
2505       pl->p_hostile = packet->hostile;
2506       PlistNoteHostile(p_no);
2507       redrawPlayer[p_no] = 1;
2508     }
2509 }
2510 
handlePlyrLogin(struct plyr_login_spacket * packet,int sock)2511 void    handlePlyrLogin(struct plyr_login_spacket *packet, int sock)
2512 {
2513   int p_no = packet->pnum;
2514   struct player *pl;
2515 
2516 #ifdef CORRUPTED_PACKETS
2517   if (sock == udpSock)
2518     {
2519       fprintf(stderr, "garbage packet discarded.\n");
2520       return;
2521     }
2522   if (packet->pnum < 0 || packet->pnum >= MAXPLAYER)
2523     {
2524       fprintf(stderr, "handlePlyrLogin: bad index %d\n", p_no);
2525       return;
2526     }
2527   packet->name[sizeof(packet->name) - 1] = '\0';
2528   packet->monitor[sizeof(packet->monitor) - 1] = '\0';
2529   packet->login[sizeof(packet->login) - 1] = '\0';
2530 #endif
2531 
2532   pl = &players[p_no];
2533 
2534   if (identityBlind) {
2535     strcpy(pl->p_name, "");
2536     strcpy(pl->p_monitor, "");
2537     strcpy(pl->p_login, "");
2538     pl->p_stats.st_rank = 0;
2539   } else {
2540     strcpy(pl->p_name, packet->name);
2541     strcpyp_return(pl->p_monitor, packet->monitor, sizeof(pl->p_monitor));
2542     strcpy(pl->p_login, packet->login);
2543     pl->p_stats.st_rank = packet->rank;
2544   }
2545 
2546   if (p_no == me->p_no)
2547     {
2548       /* This is me.  Set some stats */
2549       if (lastRank == -1)
2550 	{
2551 	  if (loggedIn)
2552 	    {
2553 	      lastRank = packet->rank;
2554 	    }
2555 	}
2556       else
2557 	{
2558 	  if (lastRank != packet->rank)
2559 	    {
2560 	      lastRank = packet->rank;
2561 	      promoted = 1;
2562 	    }
2563 	}
2564     }
2565 
2566   PlistNoteUpdate(p_no);
2567 
2568   if (gather_stats) {
2569     /* STATS_SP_PLAYER:PNUN,RANK,NAME,MONITOR,LOGIN */
2570     fprintf(statsFile, "\nSTATS_SP_PL_LOGIN:\t");
2571     fprintf(statsFile, "%d\t%d\t%s\t%s\t%s",
2572             ((struct plyr_login_spacket *) packet)->pnum,
2573             ((struct plyr_login_spacket *) packet)->rank,
2574             ((struct plyr_login_spacket *) packet)->name,
2575             ((struct plyr_login_spacket *) packet)->monitor,
2576             ((struct plyr_login_spacket *) packet)->login);
2577   }
2578 }
2579 
handleStats(struct stats_spacket * packet)2580 void    handleStats(struct stats_spacket *packet)
2581 {
2582   int p_no = packet->pnum;
2583   struct player *pl;
2584 
2585 #ifdef CORRUPTED_PACKETS
2586   if (p_no < 0 || p_no >= MAXPLAYER)
2587     {
2588       fprintf(stderr, "handleStats: bad index %d\n", p_no);
2589       return;
2590     }
2591 #endif
2592 
2593   pl = &players[p_no];
2594 
2595   pl->p_stats.st_tkills = ntohl(packet->tkills);
2596   pl->p_stats.st_tlosses = ntohl(packet->tlosses);
2597   pl->p_stats.st_kills = ntohl(packet->kills);
2598   pl->p_stats.st_losses = ntohl(packet->losses);
2599   pl->p_stats.st_tticks = ntohl(packet->tticks);
2600   pl->p_stats.st_tplanets = ntohl(packet->tplanets);
2601   pl->p_stats.st_tarmsbomb = ntohl(packet->tarmies);
2602   pl->p_stats.st_sbkills = ntohl(packet->sbkills);
2603   pl->p_stats.st_sblosses = ntohl(packet->sblosses);
2604   pl->p_stats.st_armsbomb = ntohl(packet->armies);
2605   pl->p_stats.st_planets = ntohl(packet->planets);
2606 
2607   if ((pl->p_ship.s_type == STARBASE) && (SBhours))
2608     {
2609       pl->p_stats.st_sbticks = ntohl(packet->maxkills);
2610     }
2611   else
2612     {
2613       pl->p_stats.st_maxkills = ntohl(packet->maxkills) / 100.0;
2614     }
2615   pl->p_stats.st_sbmaxkills = ntohl(packet->sbmaxkills) / 100.0;
2616 
2617   /* For some reason, we get updates for freed players.  When this
2618   happens, don't bother to update the player list. */
2619   if (pl->p_status != PFREE)
2620     PlistNoteUpdate(p_no);
2621 }
2622 
handlePlyrInfo(struct plyr_info_spacket * packet)2623 void    handlePlyrInfo(struct plyr_info_spacket *packet)
2624 {
2625   int p_no = packet->pnum;
2626   struct player *pl;
2627   static int lastship = -1;
2628 
2629 #ifdef CORRUPTED_PACKETS
2630   if (p_no < 0 || p_no >= MAXPLAYER)
2631     {
2632       fprintf(stderr, "handlePlyrInfo: bad index %d\n", p_no);
2633       return;
2634     }
2635   if (packet->team > ALLTEAM)
2636     {
2637       fprintf(stderr, "handlePlyrInfo: bad team %d\n", packet->team);
2638       return;
2639     }
2640 #endif
2641 
2642   pl = &players[p_no];
2643 
2644   PlistNoteUpdate(p_no);
2645   if ((pl->p_team != packet->team) ||		 /* Check 0 system default */
2646       ((pl->p_team == 0) && (pl->p_mapchars[0] != teamlet[0])))
2647     {
2648       pl->p_team = packet->team;
2649       pl->p_mapchars[0] = teamlet[pl->p_team];
2650       PlistNoteArrive(p_no);
2651 
2652       if (pl == me)
2653 	redrawall = 1;				 /* Update the map if I * *
2654 						  * change teams */
2655     }
2656 
2657   getship(&pl->p_ship, packet->shiptype);
2658   pl->p_mapchars[1] = shipnos[pl->p_no];
2659 
2660 
2661   if (me == pl && lastship != me->p_ship.s_type)
2662     {
2663       redrawTstats();
2664       calibrate_stats();
2665       redrawStats();				 /* TSH */
2666     }
2667   redrawPlayer[p_no] = 1;
2668 
2669   if (gather_stats) {
2670     /*STATS_SP_PLAYER_INFO:\tPNUM\tSHIPTYPE\tTEAM*/
2671     fprintf(statsFile, "\nSTATS_SP_PLAYER_INFO:\t");
2672     fprintf(statsFile, "%d\t%d\t%d",
2673             ((struct plyr_info_spacket *) packet)->pnum,
2674             ((struct plyr_info_spacket *) packet)->shiptype,
2675             ((struct plyr_info_spacket *) packet)->team);
2676   }
2677 }
2678 
sendUpdatePacket(LONG speed)2679 void sendUpdatePacket(LONG speed)
2680 {
2681   struct updates_cpacket packet;
2682 
2683   packet.type = CP_UPDATES;
2684   timerDelay = speed;
2685   packet.usecs = htonl(speed);
2686   sendServerPacket((struct player_spacket *) &packet);
2687 }
2688 
handlePlanetLoc(struct planet_loc_spacket * packet)2689 void    handlePlanetLoc(struct planet_loc_spacket *packet)
2690 {
2691   int pl_no = packet->pnum;
2692   struct planet *pl;
2693 
2694 #ifdef CORRUPTED_PACKETS
2695   if (pl_no < 0 || pl_no >= MAXPLANETS)
2696     {
2697       fprintf(stderr, "handlePlanetLoc: bad index\n");
2698       return;
2699     }
2700 #endif
2701 
2702   pl = &planets[pl_no];
2703   pl_update[pl_no].plu_x = pl->pl_x;
2704   pl_update[pl_no].plu_y = pl->pl_y;
2705 
2706   if (pl_update[pl_no].plu_update != -1)
2707     {
2708       pl_update[pl_no].plu_update = 1;
2709     }
2710   else
2711     pl_update[pl_no].plu_update = 0;
2712 
2713   pl->pl_x = ntohl(packet->x);
2714   pl->pl_y = ntohl(packet->y);
2715   strcpy(pl->pl_name, packet->name);
2716   pl->pl_namelen = strlen(packet->name);
2717   pl->pl_flags |= (PLREDRAW | PLCLEAR);
2718   reinitPlanets = 1;
2719 
2720 #ifdef ROTATERACE
2721   if (rotate)
2722     {
2723       rotate_coord(&pl->pl_x, &pl->pl_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
2724     }
2725 #endif
2726 
2727   if (gather_stats) {
2728     /*STATS_SP_PLANET_LOC:\tPNUM\tX\tY\tNAME*/
2729     fprintf(statsFile, "\nSTATS_SP_PLANET_LOC:\t");
2730     fprintf(statsFile, "%d\t%d\t%d\t%s",
2731             ((struct planet_loc_spacket *) packet)->pnum,
2732             ntohl(((struct planet_loc_spacket *) packet)->x),
2733             ntohl(((struct planet_loc_spacket *) packet)->y),
2734             ((struct planet_loc_spacket *) packet)->name);
2735   }
2736 }
2737 
2738 
handleReserved(struct reserved_spacket * packet,int sock)2739 void    handleReserved(struct reserved_spacket *packet, int sock)
2740 {
2741   struct reserved_cpacket response;
2742 
2743   bzero(&response, sizeof(response));
2744 #ifdef CORRUPTED_PACKETS
2745   if (sock == udpSock)
2746     {
2747       fprintf(stderr, "garbage Reserved packet discarded.\n");
2748       return;
2749     }
2750 #endif
2751 
2752 #if !defined(BORG)
2753 
2754 #ifndef RSA
2755   encryptReservedPacket(packet, &response, serverName, me->p_no);
2756   sendServerPacket((struct player_spacket *) &response);
2757 #else
2758 
2759   if (RSA_Client)
2760     {						 /* can use -o option for old
2761 						  * * * blessing */
2762       /* client sends back a 'reserved' packet just saying RSA_VERSION info */
2763       /* theoretically, the server then sends off a rsa_key_spacket * for the
2764        * * * client to then respond to */
2765       warning(RSA_VERSION);
2766       STRNCPY(response.resp, RSA_VERSION, RESERVED_SIZE);
2767       MCOPY(packet->data, response.data, RESERVED_SIZE);
2768       response.type = CP_RESERVED;
2769 
2770 #ifdef DEBUG
2771       printf("Sending RSA reserved response\n");
2772 #endif
2773     }
2774   else
2775     {
2776       /* If server gods don't like NEWMACRO/SMARTMACRO they better install *
2777        * * RSA... */
2778       UseNewMacro = 1;
2779       UseSmartMacro = 1;
2780       encryptReservedPacket(packet, &response, serverName, me->p_no);
2781     }
2782 
2783   sendServerPacket((struct player_spacket *) &response);
2784 #endif /* RSA */
2785 
2786 #endif /* defined(BORG) */
2787 }
2788 
handleShipCap(struct ship_cap_spacket * packet)2789 void    handleShipCap(struct ship_cap_spacket *packet)
2790 {
2791   unsigned short stype;
2792 
2793   stype = ntohs(packet->s_type);
2794   shipvals[stype].s_torpspeed = ntohs(packet->s_torpspeed);
2795   shipvals[stype].s_maxshield = ntohl(packet->s_maxshield);
2796   shipvals[stype].s_maxdamage = ntohl(packet->s_maxdamage);
2797   shipvals[stype].s_maxegntemp = ntohl(packet->s_maxegntemp);
2798   shipvals[stype].s_maxwpntemp = ntohl(packet->s_maxwpntemp);
2799   shipvals[stype].s_maxarmies = ntohs(packet->s_maxarmies);
2800   shipvals[stype].s_maxfuel = ntohl(packet->s_maxfuel);
2801   shipvals[stype].s_maxspeed = ntohl(packet->s_maxspeed);
2802   shipvals[stype].s_width = ntohs(packet->s_width);
2803   shipvals[stype].s_height = ntohs(packet->s_height);
2804   shipvals[stype].s_phaserdamage = ntohs(packet->s_phaserrange);
2805   getship(myship, myship->s_type);
2806 }
2807 
2808 static void
handleGeneric32_a(struct generic_32_spacket_a * packet)2809 handleGeneric32_a (struct generic_32_spacket_a *packet)
2810 {
2811     me->p_repair_time = packet->repair_time;
2812     me->pl_orbit = packet->pl_orbit;
2813 }
2814 
2815 static void
handleGeneric32_b(struct generic_32_spacket_b * packet)2816 handleGeneric32_b (struct generic_32_spacket_b *packet)
2817 {
2818     int rate;
2819     static int unsafe = GU_UNSAFE;
2820     static int idling = 0;
2821     static int saved_ups = 0;
2822 
2823     me->p_repair_time = ntohs(packet->repair_time);
2824     me->pl_orbit = packet->pl_orbit;
2825     context->gameup = ntohs(packet->gameup);
2826     context->tournament_teams = packet->tournament_teams;
2827     context->tournament_age = packet->tournament_age;
2828     context->tournament_age_units = packet->tournament_age_units;
2829     context->tournament_remain = packet->tournament_remain;
2830     context->tournament_remain_units = packet->tournament_remain_units;
2831     context->starbase_remain = packet->starbase_remain;
2832     context->team_remain = packet->team_remain;
2833 
2834     /* to maintain update rate when safe-idle, set updatespersec.idle: -1 */
2835 
2836     rate = intDefault("updatespersec.idle", 1);
2837     if ((unsafe ^ context->gameup) & GU_UNSAFE) {
2838       unsafe = context->gameup;
2839       if (context->gameup & GU_UNSAFE) {
2840         if (idling) {
2841 	  if (rate < 0) {
2842 	    warning("Safe idle stop.");
2843 	  } else {
2844 	    sendUpdatePacket(1000000 / saved_ups);
2845 	    warning("Safe idle stop, normal update rate resumed.");
2846 	  }
2847 	  if (context->tournament_age_units == 's' &&
2848 	      context->tournament_age < 5 &&
2849 	      booleanDefault("game-begin-while-idle-beep", 1)) W_Beep();
2850 	  idling = 0;
2851         }
2852       } else {
2853         if (!(context->gameup & GU_UNSAFE)) {
2854           if (!idling) {
2855 	    if (rate < 0) {
2856 	      warning("Safe idle start.");
2857 	    } else {
2858 	      saved_ups = client_ups;
2859 	      sendUpdatePacket(1000000 / rate);
2860 	      idling++;
2861 	      warning("Safe idle start, update rate reduced.");
2862 	    }
2863           }
2864         }
2865       }
2866     }
2867 }
2868 
2869 static void
handleGeneric32(struct generic_32_spacket * packet)2870 handleGeneric32 (struct generic_32_spacket *packet)
2871 {
2872   switch (packet->version) {
2873   case 0x60+GENERIC_32_VERSION_A:
2874     handleGeneric32_a((struct generic_32_spacket_a *) packet);
2875     break;
2876   case 0x60+GENERIC_32_VERSION_B:
2877     handleGeneric32_b((struct generic_32_spacket_b *) packet);
2878     break;
2879   }
2880 }
2881 
2882 void
handleRank(struct rank_spacket * packet)2883 handleRank (struct rank_spacket *packet)
2884 {
2885   int i = packet->rnum;
2886   int j = packet->rmax + 1;
2887 
2888   if (i < 0 || j < 0 || i > j) return;
2889   if (j > nranks) {
2890     ranks = (struct rank *) realloc(ranks, j * sizeof(struct rank));
2891     memset(&ranks[nranks], 0, (j - nranks) * sizeof(struct rank));
2892   }
2893   nranks = j;
2894   W_ChangeBorder(rankw, gColor);
2895   packet->name[15] = 0;
2896   ranks[i].name = strdup(packet->name);
2897   packet->cname[7] = 0;
2898   ranks[i].cname = strdup(packet->cname);
2899   ranks[i].hours = (float) (ntohl (packet->hours) / 100.0);
2900   ranks[i].ratings = (float) (ntohl (packet->ratings) / 100.0);
2901   ranks[i].offense = (float) (ntohl (packet->offense) / 100.0);
2902 }
2903 
dump_prefix(const char * abbr,const char * name)2904 static void dump_prefix(const char *abbr, const char *name) {
2905   fprintf(stderr, "%-10s %-30s ", abbr, name);
2906 }
2907 
2908 #define dump_stat(STAT) { \
2909     fprintf(stderr, " %8u\n", (unsigned int) ltd.STAT); \
2910 }
2911 
2912 #define dump_max(STAT) { \
2913     fprintf(stderr, " %8u\n", (unsigned int) ltd.STAT); \
2914 }
2915 
2916 void
handleLtd(struct ltd_spacket * packet)2917 handleLtd (struct ltd_spacket *packet)
2918 {
2919   if (packet->version != LTD_VERSION) return;
2920 
2921   struct ltd_stats ltd;
2922 
2923   ltd.kills.total                     = ntohl(packet->kt);
2924   ltd.kills.max                       = (double)(ntohl(packet->kmax)) / 100.0;
2925   ltd.kills.first                     = ntohl(packet->k1);
2926   ltd.kills.first_potential           = ntohl(packet->k1p);
2927   ltd.kills.first_converted           = ntohl(packet->k1c);
2928   ltd.kills.second                    = ntohl(packet->k2);
2929   ltd.kills.second_potential          = ntohl(packet->k2p);
2930   ltd.kills.second_converted          = ntohl(packet->k2c);
2931   ltd.kills.phasered                  = ntohl(packet->kbp);
2932   ltd.kills.torped                    = ntohl(packet->kbt);
2933   ltd.kills.plasmaed                  = ntohl(packet->kbs);
2934   ltd.deaths.total                    = ntohl(packet->dt);
2935   ltd.deaths.potential                = ntohl(packet->dpc);
2936   ltd.deaths.converted                = ntohl(packet->dcc);
2937   ltd.deaths.dooshed                  = ntohl(packet->ddc);
2938   ltd.deaths.phasered                 = ntohl(packet->dbp);
2939   ltd.deaths.torped                   = ntohl(packet->dbt);
2940   ltd.deaths.plasmaed                 = ntohl(packet->dbs);
2941   ltd.deaths.acc                      = ntohl(packet->acc);
2942   ltd.planets.taken                   = ntohl(packet->ptt);
2943   ltd.planets.destroyed               = ntohl(packet->pdt);
2944   ltd.bomb.planets                    = ntohl(packet->bpt);
2945   ltd.bomb.planets_8                  = ntohl(packet->bp8);
2946   ltd.bomb.planets_core               = ntohl(packet->bpc);
2947   ltd.bomb.armies                     = ntohl(packet->bat);
2948   ltd.bomb.armies_8                   = ntohl(packet->ba8);
2949   ltd.bomb.armies_core                = ntohl(packet->bac);
2950   ltd.ogged.armies                    = ntohl(packet->oat);
2951   ltd.ogged.dooshed                   = ntohl(packet->odc);
2952   ltd.ogged.converted                 = ntohl(packet->occ);
2953   ltd.ogged.potential                 = ntohl(packet->opc);
2954   ltd.ogged.bigger_ship               = ntohl(packet->ogc);
2955   ltd.ogged.same_ship                 = ntohl(packet->oec);
2956   ltd.ogged.smaller_ship              = ntohl(packet->olc);
2957   ltd.ogged.sb_armies                 = ntohl(packet->osba);
2958   ltd.ogged.friendly                  = ntohl(packet->ofc);
2959   ltd.ogged.friendly_armies           = ntohl(packet->ofa);
2960   ltd.armies.total                    = ntohl(packet->at);
2961   ltd.armies.attack                   = ntohl(packet->aa);
2962   ltd.armies.reinforce                = ntohl(packet->ar);
2963   ltd.armies.ferries                  = ntohl(packet->af);
2964   ltd.armies.killed                   = ntohl(packet->ak);
2965   ltd.carries.total                   = ntohl(packet->ct);
2966   ltd.carries.partial                 = ntohl(packet->cp);
2967   ltd.carries.completed               = ntohl(packet->cc);
2968   ltd.carries.attack                  = ntohl(packet->ca);
2969   ltd.carries.reinforce               = ntohl(packet->cr);
2970   ltd.carries.ferries                 = ntohl(packet->cf);
2971   ltd.ticks.total                     = ntohl(packet->tt);
2972   ltd.ticks.yellow                    = ntohl(packet->tyel);
2973   ltd.ticks.red                       = ntohl(packet->tred);
2974   ltd.ticks.zone[0]                   = ntohl(packet->tz0);
2975   ltd.ticks.zone[1]                   = ntohl(packet->tz1);
2976   ltd.ticks.zone[2]                   = ntohl(packet->tz2);
2977   ltd.ticks.zone[3]                   = ntohl(packet->tz3);
2978   ltd.ticks.zone[4]                   = ntohl(packet->tz4);
2979   ltd.ticks.zone[5]                   = ntohl(packet->tz5);
2980   ltd.ticks.zone[6]                   = ntohl(packet->tz6);
2981   ltd.ticks.zone[7]                   = ntohl(packet->tz7);
2982   ltd.ticks.potential                 = ntohl(packet->tpc);
2983   ltd.ticks.carrier                   = ntohl(packet->tcc);
2984   ltd.ticks.repair                    = ntohl(packet->tr);
2985   ltd.damage_repaired                 = ntohl(packet->dr);
2986   ltd.weapons.phaser.fired            = ntohl(packet->wpf);
2987   ltd.weapons.phaser.hit              = ntohl(packet->wph);
2988   ltd.weapons.phaser.damage.inflicted = ntohl(packet->wpdi);
2989   ltd.weapons.phaser.damage.taken     = ntohl(packet->wpdt);
2990   ltd.weapons.torps.fired             = ntohl(packet->wtf);
2991   ltd.weapons.torps.hit               = ntohl(packet->wth);
2992   ltd.weapons.torps.detted            = ntohl(packet->wtd);
2993   ltd.weapons.torps.selfdetted        = ntohl(packet->wts);
2994   ltd.weapons.torps.wall              = ntohl(packet->wtw);
2995   ltd.weapons.torps.damage.inflicted  = ntohl(packet->wtdi);
2996   ltd.weapons.torps.damage.taken      = ntohl(packet->wtdt);
2997   ltd.weapons.plasma.fired            = ntohl(packet->wsf);
2998   ltd.weapons.plasma.hit              = ntohl(packet->wsh);
2999   ltd.weapons.plasma.phasered         = ntohl(packet->wsp);
3000   ltd.weapons.plasma.wall             = ntohl(packet->wsw);
3001   ltd.weapons.plasma.damage.inflicted = ntohl(packet->wsdi);
3002   ltd.weapons.plasma.damage.taken     = ntohl(packet->wsdt);
3003 
3004   return;
3005 
3006   fprintf(stderr, "SP_LTD test output begins\n");
3007   dump_prefix("kt",   "kills total");			dump_stat(kills.total);
3008   dump_prefix("kmax", "kills max");			dump_max(kills.max);
3009   dump_prefix("k1",   "kills first");			dump_stat(kills.first);
3010   dump_prefix("k1p",  "kills first potential");		dump_stat(kills.first_potential);
3011   dump_prefix("k1c",  "kills first converted");		dump_stat(kills.first_converted);
3012   dump_prefix("k2",   "kills second");			dump_stat(kills.second);
3013   dump_prefix("k2p",  "kills second potential");	dump_stat(kills.second_potential);
3014   dump_prefix("k2c",  "kills second converted");	dump_stat(kills.second_converted);
3015   dump_prefix("kbp",  "kills by phaser");		dump_stat(kills.phasered);
3016   dump_prefix("kbt",  "kills by torp");			dump_stat(kills.torped);
3017   dump_prefix("kbs",  "kills by smack");		dump_stat(kills.plasmaed);
3018   dump_prefix("dt",   "deaths total");			dump_stat(deaths.total);
3019   dump_prefix("dpc",  "deaths as potential carrier");	dump_stat(deaths.potential);
3020   dump_prefix("dcc",  "deaths as converted carrier");	dump_stat(deaths.converted);
3021   dump_prefix("ddc",  "deaths as dooshed carrier");	dump_stat(deaths.dooshed);
3022   dump_prefix("dbp",  "deaths by phaser");		dump_stat(deaths.phasered);
3023   dump_prefix("dbt",  "deaths by torp");		dump_stat(deaths.torped);
3024   dump_prefix("dbs",  "deaths by smack");		dump_stat(deaths.plasmaed);
3025   dump_prefix("acc",  "actual carriers created");	dump_stat(deaths.acc);
3026   dump_prefix("ptt",  "planets taken total");		dump_stat(planets.taken);
3027   dump_prefix("pdt",  "planets destroyed total");	dump_stat(planets.destroyed);
3028   dump_prefix("bpt",  "bombed planets total");		dump_stat(bomb.planets);
3029   dump_prefix("bp8",  "bombed planets <=8");		dump_stat(bomb.planets_8);
3030   dump_prefix("bpc",  "bombed planets core");		dump_stat(bomb.planets_core);
3031   dump_prefix("bat",  "bombed armies total");		dump_stat(bomb.armies);
3032   dump_prefix("ba8",  "bombed_armies <= 8");		dump_stat(bomb.armies_8);
3033   dump_prefix("bac",  "bombed armies core");		dump_stat(bomb.armies_core);
3034   dump_prefix("oat",  "ogged armies total");		dump_stat(ogged.armies);
3035   dump_prefix("odc",  "ogged dooshed carrier");		dump_stat(ogged.dooshed);
3036   dump_prefix("occ",  "ogged converted carrier");	dump_stat(ogged.converted);
3037   dump_prefix("opc",  "ogged potential carrier");	dump_stat(ogged.potential);
3038   dump_prefix("o>c",  "ogged bigger carrier");		dump_stat(ogged.bigger_ship);
3039   dump_prefix("o=c",  "ogged same carrier");		dump_stat(ogged.same_ship);
3040   dump_prefix("o<c",  "ogger smaller carrier");		dump_stat(ogged.smaller_ship);
3041   dump_prefix("osba", "ogged sb armies");		dump_stat(ogged.sb_armies);
3042   dump_prefix("ofc",  "ogged friendly carrier");	dump_stat(ogged.friendly);
3043   dump_prefix("ofa",  "ogged friendly armies");		dump_stat(ogged.friendly_armies);
3044   dump_prefix("at",   "armies carried total");		dump_stat(armies.total);
3045   dump_prefix("aa",   "armies used to attack");		dump_stat(armies.attack);
3046   dump_prefix("ar",   "armies used to reinforce");	dump_stat(armies.reinforce);
3047   dump_prefix("af",   "armies ferried");		dump_stat(armies.ferries);
3048   dump_prefix("ak",   "armies killed");			dump_stat(armies.killed);
3049   dump_prefix("ct",   "carries total");			dump_stat(carries.total);
3050   dump_prefix("cp",   "carries partial");		dump_stat(carries.partial);
3051   dump_prefix("cc",   "carries completed");		dump_stat(carries.completed);
3052   dump_prefix("ca",   "carries to attack");		dump_stat(carries.attack);
3053   dump_prefix("cr",   "carries to reinforce");		dump_stat(carries.reinforce);
3054   dump_prefix("cf",   "carries to ferry");		dump_stat(carries.ferries);
3055   dump_prefix("tt",   "ticks total");			dump_stat(ticks.total);
3056   dump_prefix("tyel", "ticks in yellow");		dump_stat(ticks.yellow);
3057   dump_prefix("tred", "ticks in red");			dump_stat(ticks.red);
3058   dump_prefix("tz0",  "ticks in zone 0");		dump_stat(ticks.zone[0]);
3059   dump_prefix("tz1",  "ticks in zone 1");		dump_stat(ticks.zone[1]);
3060   dump_prefix("tz2",  "ticks in zone 2");		dump_stat(ticks.zone[2]);
3061   dump_prefix("tz3",  "ticks in zone 3");		dump_stat(ticks.zone[3]);
3062   dump_prefix("tz4",  "ticks in zone 4");		dump_stat(ticks.zone[4]);
3063   dump_prefix("tz5",  "ticks in zone 5");		dump_stat(ticks.zone[5]);
3064   dump_prefix("tz6",  "ticks in zone 6");		dump_stat(ticks.zone[6]);
3065   dump_prefix("tz7",  "ticks in zone 7");		dump_stat(ticks.zone[7]);
3066   dump_prefix("tpc",  "ticks as potential carrier");	dump_stat(ticks.potential);
3067   dump_prefix("tcc",  "ticks as carrier++");		dump_stat(ticks.carrier);
3068   dump_prefix("tr",   "ticks in repair");		dump_stat(ticks.repair);
3069   dump_prefix("dr",   "damage repaired");		dump_stat(damage_repaired);
3070   dump_prefix("wpf",  "weap phaser fired");		dump_stat(weapons.phaser.fired);
3071   dump_prefix("wph",  "weap phaser hit");		dump_stat(weapons.phaser.hit);
3072   dump_prefix("wpdi", "weap phaser damage inflicted");	dump_stat(weapons.phaser.damage.inflicted);
3073   dump_prefix("wpdt", "weap phaser damage taken");	dump_stat(weapons.phaser.damage.taken);
3074   dump_prefix("wtf",  "weap torp fired");		dump_stat(weapons.torps.fired);
3075   dump_prefix("wth",  "weap torp hit");			dump_stat(weapons.torps.hit);
3076   dump_prefix("wtd",  "weap torp detted");		dump_stat(weapons.torps.detted);
3077   dump_prefix("wts",  "weap torp self detted");		dump_stat(weapons.torps.selfdetted);
3078   dump_prefix("wtw",  "weap torp hit wall");		dump_stat(weapons.torps.wall);
3079   dump_prefix("wtdi", "weap torp damage inflicted");	dump_stat(weapons.torps.damage.inflicted);
3080   dump_prefix("wtdt", "weap torp damage taken");	dump_stat(weapons.torps.damage.taken);
3081   dump_prefix("wsf",  "weap smack fired");		dump_stat(weapons.plasma.fired);
3082   dump_prefix("wsh",  "weap smack hit");		dump_stat(weapons.plasma.hit);
3083   dump_prefix("wsp",  "weap smack phasered");		dump_stat(weapons.plasma.phasered);
3084   dump_prefix("wsw",  "weap smack hit wall");		dump_stat(weapons.plasma.wall);
3085   dump_prefix("wsdi", "weap smack damage inflicted");	dump_stat(weapons.plasma.damage.inflicted);
3086   dump_prefix("wsdt", "weap smack damage taken");	dump_stat(weapons.plasma.damage.taken);
3087   fprintf(stderr, "SP_LTD test output ends\n");
3088 }
3089 
3090 #ifdef RSA
handleRSAKey(struct rsa_key_spacket * packet)3091 void    handleRSAKey(struct rsa_key_spacket *packet)
3092 {
3093   struct rsa_key_cpacket response;
3094   struct sockaddr_in saddr;
3095   socklen_t len;
3096   unsigned char *data;
3097 
3098 #ifdef GATEWAY
3099   extern unsigned LONG netaddr;
3100   extern int serv_port;
3101 #endif
3102 
3103   bzero(&response, sizeof(response));
3104   response.type = CP_RSA_KEY;
3105   /* encryptRSAPacket (packet, &response);      old style rsa-client  */
3106 
3107 #ifdef GATEWAY
3108   /* if we didn't get it from -H, go ahead and query the socket */
3109   if (netaddr == 0)
3110     {
3111       len = sizeof(saddr);
3112       if (getpeername(sock, (struct sockaddr *) &saddr, &len) < 0)
3113 	{
3114 	  perror("getpeername(sock)");
3115 	  terminate(1);
3116 	}
3117     }
3118   else
3119     {
3120       saddr.sin_addr.s_addr = htonl(netaddr);
3121       saddr.sin_port = htons(serv_port);
3122     }
3123 #else
3124   /* query the socket to determine the remote host (ATM) */
3125   len = sizeof(saddr);
3126   if (getpeername(sock, (struct sockaddr *) &saddr, &len) < 0)
3127     {
3128       perror("getpeername(sock)");
3129       terminate(1);
3130     }
3131 #endif
3132 
3133   /* replace the first few bytes of the message */
3134   /* will be the low order bytes of the number */
3135   data = packet->data;
3136   MCOPY(&saddr.sin_addr.s_addr, data, sizeof(saddr.sin_addr.s_addr));
3137   data += sizeof(saddr.sin_addr.s_addr);
3138   MCOPY(&saddr.sin_port, data, sizeof(saddr.sin_port));
3139 
3140   rsa_black_box(response.resp, packet->data, response.public, response.global);
3141 
3142   sendServerPacket((struct player_spacket *) &response);
3143 }
3144 #endif
3145 
3146 #ifdef INCLUDE_SCAN
handleScan(packet)3147 void    handleScan(packet)
3148 struct scan_spacket *packet;
3149 {
3150   struct player *pp;
3151 
3152 #ifdef CORRUPTED_PACKETS
3153   if (packet->pnum >= MAXPLAYER)
3154     {
3155       fprintf(stderr, "handleScan: bad index\n");
3156       return;
3157     }
3158 #endif
3159 
3160   if (packet->success)
3161     {
3162       pp = &players[packet->pnum];
3163       pp->p_fuel = ntohl(packet->p_fuel);
3164       pp->p_armies = ntohl(packet->p_armies);
3165       pp->p_shield = ntohl(packet->p_shield);
3166       pp->p_damage = ntohl(packet->p_damage);
3167       pp->p_etemp = ntohl(packet->p_etemp);
3168       pp->p_wtemp = ntohl(packet->p_wtemp);
3169       informScan(packet->pnum);
3170     }
3171 }
3172 
informScan(p)3173 informScan(p)
3174 int     p;
3175 {
3176 }
3177 #endif /* INCLUDE_SCAN */
3178 
3179 /* UDP stuff */
sendUdpReq(int req)3180 void sendUdpReq(int req)
3181 {
3182   struct udp_req_cpacket packet;
3183 
3184   memset(&packet, 0, sizeof(struct udp_req_cpacket));
3185   packet.type = CP_UDP_REQ;
3186   packet.request = req;
3187 
3188   if (req >= COMM_MODE)
3189     {
3190       packet.request = COMM_MODE;
3191       packet.connmode = req - COMM_MODE;
3192       sendServerPacket((struct player_spacket *) &packet);
3193       return;
3194     }
3195   if (req == COMM_UPDATE)
3196     {
3197 
3198 #ifdef SHORT_PACKETS
3199       if (recv_short)
3200 	{					 /* not necessary */
3201 	  /* Let the client do the work, and not the network :-) */
3202 
3203 	  resetWeaponInfo();
3204 	}
3205 #endif
3206 
3207       sendServerPacket((struct player_spacket *) &packet);
3208       warning("Sent request for full update");
3209       return;
3210     }
3211   if (req == commModeReq)
3212     {
3213       warning("Request is in progress, do not disturb");
3214       return;
3215     }
3216   if (req == COMM_UDP)
3217     {
3218       /* open UDP port */
3219       if (openUdpConn() >= 0)
3220 	{
3221 	  UDPDIAG(("Bound to local port %d on fd %d\n", udpLocalPort, udpSock));
3222 	}
3223       else
3224 	{
3225 	  UDPDIAG(("Bind to local port %d failed\n", udpLocalPort));
3226 	  commModeReq = COMM_TCP;
3227 	  commStatus = STAT_CONNECTED;
3228 	  commSwitchTimeout = 0;
3229 	  if (udpWin)
3230 	    udprefresh(UDP_STATUS);
3231 	  warning("Unable to establish UDP connection");
3232 
3233 	  return;
3234 	}
3235     }
3236   /* send the request */
3237   packet.type = CP_UDP_REQ;
3238   packet.request = req;
3239   packet.port = htonl(udpLocalPort);
3240 
3241 #ifdef GATEWAY
3242   if (!strcmp(serverName, gw_mach))
3243     {
3244       packet.port = htons(gw_serv_port);	 /* gw port that server * *
3245 						  * should call */
3246       UDPDIAG(("+ Telling server to contact us on %d\n", gw_serv_port));
3247     }
3248 #endif
3249 
3250 #ifdef UDP_PORTSWAP
3251   if (portSwap)
3252     packet.connmode = CONNMODE_PORT;		 /* have him send his port */
3253   else
3254 #endif
3255     packet.connmode = CONNMODE_PACKET;		 /* we get addr from packet */
3256 
3257   sendServerPacket((struct player_spacket *) &packet);
3258 
3259   /* update internal state stuff */
3260   commModeReq = req;
3261   if (req == COMM_TCP)
3262     commStatus = STAT_SWITCH_TCP;
3263   else
3264     commStatus = STAT_SWITCH_UDP;
3265   commSwitchTimeout = 25;			 /* wait 25 updates (about *
3266 						  * * five seconds) */
3267 
3268   UDPDIAG(("Sent request for %s mode\n", (req == COMM_TCP) ?
3269 	   "TCP" : "UDP"));
3270 
3271 #ifdef UDP_PORTSWAP
3272   if (!portSwap)
3273 #endif
3274   if ((req == COMM_UDP) && recvUdpConn() < 0)
3275     {
3276       UDPDIAG(("Sending TCP reset message\n"));
3277       packet.request = COMM_TCP;
3278       packet.port = 0;
3279       commModeReq = COMM_TCP;
3280       sendServerPacket((struct player_spacket *) &packet);
3281       /* we will likely get a SWITCH_UDP_OK later; better ignore it */
3282       commModeReq = COMM_TCP;
3283       commStatus = STAT_CONNECTED;
3284       commSwitchTimeout = 0;
3285     }
3286 
3287   if (udpWin)
3288     udprefresh(UDP_STATUS);
3289 }
3290 
handleUdpReply(struct udp_reply_spacket * packet)3291 void    handleUdpReply(struct udp_reply_spacket *packet)
3292 {
3293   struct udp_req_cpacket response;
3294 
3295   UDPDIAG(("Received UDP reply %d\n", packet->reply));
3296   commSwitchTimeout = 0;
3297 
3298   memset(&response, 0, sizeof(struct udp_req_cpacket));
3299   response.type = CP_UDP_REQ;
3300 
3301   switch (packet->reply)
3302     {
3303     case SWITCH_TCP_OK:
3304       if (commMode == COMM_TCP)
3305 	{
3306 	  UDPDIAG(("Got SWITCH_TCP_OK while in TCP mode; ignoring\n"));
3307 	}
3308       else
3309 	{
3310 	  commMode = COMM_TCP;
3311 	  commStatus = STAT_CONNECTED;
3312 	  warning("Switched to TCP-only connection");
3313 	  closeUdpConn();
3314 	  UDPDIAG(("UDP port closed\n"));
3315 	  if (udpWin)
3316 	    {
3317 	      udprefresh(UDP_STATUS);
3318 	      udprefresh(UDP_CURRENT);
3319 	    }
3320 	}
3321       break;
3322     case SWITCH_UDP_OK:
3323       if (commMode == COMM_UDP)
3324 	{
3325 	  UDPDIAG(("Got SWITCH_UDP_OK while in UDP mode; ignoring\n"));
3326 	}
3327       else
3328 	{
3329 	  /* the server is forcing UDP down our throat? */
3330 	  if (commModeReq != COMM_UDP)
3331 	    {
3332 	      UDPDIAG(("Got unsolicited SWITCH_UDP_OK; ignoring\n"));
3333 	    }
3334 	  else
3335 	    {
3336 
3337 #ifdef UDP_PORTSWAP
3338 	      if (portSwap)
3339 		{
3340 		  udpServerPort = ntohl(packet->port);
3341 		  if (connUdpConn() < 0)
3342 		    {
3343 		      UDPDIAG(("Unable to connect, resetting\n"));
3344 		      warning("Connection attempt failed");
3345 		      commModeReq = COMM_TCP;
3346 		      commStatus = STAT_CONNECTED;
3347 		      if (udpSock >= 0)
3348 			closeUdpConn();
3349 		      if (udpWin)
3350 			{
3351 			  udprefresh(UDP_STATUS);
3352 			  udprefresh(UDP_CURRENT);
3353 			}
3354 		      response.request = COMM_TCP;
3355 		      response.port = 0;
3356 		      goto send;
3357 		    }
3358 		}
3359 #else
3360 	      /* this came down UDP, so we MUST be connected */
3361 	      /* (do the verify thing anyway just for kicks) */
3362 #endif
3363 
3364 	      UDPDIAG(("Connected to server's UDP port\n"));
3365 	      commStatus = STAT_VERIFY_UDP;
3366 	      if (udpWin)
3367 		udprefresh(UDP_STATUS);
3368 	      response.request = COMM_VERIFY;	 /* send verify request on *
3369 						  * * UDP */
3370 	      response.port = 0;
3371 	      commSwitchTimeout = 25;		 /* wait 25 updates */
3372 	    send:
3373 	      sendServerPacket((struct player_spacket *) &response);
3374 	    }
3375 	}
3376       break;
3377     case SWITCH_DENIED:
3378       if (ntohs(packet->port))
3379 	{
3380 	  UDPDIAG(("Switch to UDP failed (different version)\n"));
3381 	  warning("UDP protocol request failed (bad version)");
3382 	}
3383       else
3384 	{
3385 	  UDPDIAG(("Switch to UDP denied\n"));
3386 	  warning("UDP protocol request denied");
3387 	}
3388       commModeReq = commMode;
3389       commStatus = STAT_CONNECTED;
3390       commSwitchTimeout = 0;
3391       if (udpWin)
3392 	udprefresh(UDP_STATUS);
3393       if (udpSock >= 0)
3394 	closeUdpConn();
3395       break;
3396     case SWITCH_VERIFY:
3397       UDPDIAG(("Received UDP verification\n"));
3398       break;
3399     default:
3400       fprintf(stderr, "netrek: Got funny reply (%d) in UDP_REPLY packet\n",
3401 	      packet->reply);
3402       break;
3403     }
3404 }
3405 
3406 #define MAX_PORT_RETRY  10
openUdpConn(void)3407 static int openUdpConn(void)
3408 {
3409   struct sockaddr_in addr;
3410   struct hostent *hp;
3411   int     attempts;
3412 
3413   if (udpSock >= 0)
3414     {
3415       fprintf(stderr, "netrek: tried to open udpSock twice\n");
3416       return 0;				 /* pretend we succeeded * *
3417 						  * (this could be bad) */
3418     }
3419   if ((udpSock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
3420     {
3421       perror("netrek: unable to create DGRAM socket");
3422       return -1;
3423     }
3424 
3425 #ifdef nodef
3426   set_udp_opts(udpSock);
3427 #endif /* nodef */
3428 
3429   if (udpSock >= max_fd)
3430     max_fd = udpSock + 1;
3431 
3432   addr.sin_addr.s_addr = INADDR_ANY;
3433   addr.sin_family = AF_INET;
3434 
3435   errno = 0;
3436   udpLocalPort = (getpid() & 32767) + (RANDOM() % 256);
3437 
3438   /* if baseLocalPort is defined, we want to start from that */
3439   if (baseLocalPort)
3440     {
3441       udpLocalPort = baseLocalPort;
3442       UDPDIAG(("using base port %d\n", baseLocalPort));
3443     }
3444 
3445   for (attempts = 0; attempts < MAX_PORT_RETRY; attempts++)
3446     {
3447       while (udpLocalPort < 2048)
3448 	{
3449 	  udpLocalPort = (udpLocalPort + 10687) & 32767;
3450 	}
3451 
3452 #ifdef GATEWAY
3453       /* we need the gateway to know where to find us */
3454       if (!strcmp(serverName, gw_mach))
3455 	{
3456 	  UDPDIAG(("+ gateway test: binding to %d\n", gw_local_port));
3457 	  udpLocalPort = gw_local_port;
3458 	}
3459 #endif
3460 
3461       addr.sin_port = htons(udpLocalPort);
3462       if (bind(udpSock, (struct sockaddr *) &addr, sizeof(addr)) >= 0)
3463 	break;
3464 
3465       /* bind() failed, so find another port.  If we're tunneling through a *
3466        *
3467        * * router-based firewall, we just increment; otherwise we try to mix
3468        * it * * up a little.  The check for ports < 2048 is done above. */
3469       if (baseLocalPort)
3470 	udpLocalPort++;
3471       else
3472 	udpLocalPort = (udpLocalPort + 10687) & 32767;
3473     }
3474   if (attempts == MAX_PORT_RETRY)
3475     {
3476       perror("netrek: bind");
3477       UDPDIAG(("Unable to find a local port to bind to\n"));
3478       close(udpSock);
3479       udpSock = -1;
3480       return -1;
3481     }
3482   UDPDIAG(("Local port is %d\n", udpLocalPort));
3483 
3484   /* determine the address of the server */
3485   if (!serveraddr)
3486     {
3487       if ((addr.sin_addr.s_addr = inet_addr(serverName)) == -1)
3488 	{
3489 	  if ((hp = gethostbyname(serverName)) == NULL)
3490 	    {
3491 	      printf("Who is %s?\n", serverName);
3492 	      terminate(0);
3493 	    }
3494 	  else
3495 	    {
3496 	      addr.sin_addr.s_addr = *(LONG *) hp->h_addr;
3497 	    }
3498 	}
3499       serveraddr = addr.sin_addr.s_addr;
3500       UDPDIAG(("Found serveraddr == %s\n", inet_ntoa(addr.sin_addr)));
3501     }
3502   return 0;
3503 }
3504 
3505 #ifdef UDP_PORTSWAP
connUdpConn()3506 int connUdpConn()
3507 {
3508   struct sockaddr_in addr;
3509 
3510   addr.sin_addr.s_addr = serveraddr;
3511   addr.sin_family = AF_INET;
3512   addr.sin_port = htons(udpServerPort);
3513 
3514   UDPDIAG(("Connecting to host %s on port %d\n",
3515 	   inet_ntoa(addr.sin_addr), udpServerPort));
3516   if (connect(udpSock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
3517     {
3518       perror("netrek: unable to connect UDP socket");
3519       printUdpInfo();				 /* debug */
3520       return -1;
3521     }
3522 
3523 #ifdef nodef
3524   len = sizeof(addr);
3525   if (getsockname(udpSock, &addr, &len) < 0)
3526     {
3527       perror("netrek: unable to getsockname(UDP)");
3528       UDPDIAG(("Can't get our own socket; connection failed\n"));
3529       close(udpSock);
3530       udpSock = -1;
3531       return -1;
3532     }
3533   printf("udpLocalPort %d, getsockname port %d\n",
3534 	 udpLocalPort, addr.sin_port);
3535 #endif
3536 
3537   return 0;
3538 }
3539 #endif
3540 
recvUdpConn(void)3541 static int recvUdpConn(void)
3542 {
3543   fd_set  readfds;
3544   struct timeval to;
3545   struct sockaddr_in from;
3546   int     res;
3547   socklen_t fromlen;
3548 
3549   MZERO(&from, sizeof(from));			 /* don't get garbage if * *
3550 						  * really broken */
3551   ns_init(3);
3552 
3553   /* we patiently wait until the server sends a packet to us */
3554   /* (note that we silently eat the first one) */
3555   UDPDIAG(("Issuing recvfrom() call\n"));
3556   printUdpInfo();
3557   fromlen = sizeof(from);
3558   FD_ZERO(&readfds);
3559   FD_SET(udpSock, &readfds);
3560   to.tv_sec = 6;				 /* wait 3 seconds, then * *
3561 						  * abort */
3562   to.tv_usec = 0;
3563   if ((res = SELECT(max_fd, &readfds, 0, 0, &to)) <= 0)
3564     {
3565       if (!res)
3566 	{
3567 	  UDPDIAG(("timed out waiting for response\n"));
3568 	  warning("UDP connection request timed out");
3569 	  return -1;
3570 	}
3571       else
3572 	{
3573 	  perror("select() before recvfrom()");
3574 	  return -1;
3575 	}
3576     }
3577   if (recvfrom(udpSock, buf, BUFSIZE, 0, (struct sockaddr *) &from, &fromlen) < 0)
3578     {
3579       perror("recvfrom");
3580       UDPDIAG(("recvfrom failed, aborting UDP attempt\n"));
3581       return -1;
3582     }
3583   if (from.sin_addr.s_addr != serveraddr)
3584     {
3585       /* safe? */
3586       serveraddr = from.sin_addr.s_addr;
3587       UDPDIAG(("Warning: from different IP\n"));
3588     }
3589   if (from.sin_family != AF_INET)
3590     {
3591       UDPDIAG(("Warning: not AF_INET (%d)\n", from.sin_family));
3592     }
3593   udpServerPort = ntohs(from.sin_port);
3594   UDPDIAG(("recvfrom() succeeded; will use server port %d\n", udpServerPort));
3595 
3596 #ifdef GATEWAY
3597   if (!strcmp(serverName, gw_mach))
3598     {
3599       UDPDIAG(("+ actually, I'm going to use %d\n", gw_port));
3600       udpServerPort = gw_port;
3601       from.sin_port = htons(udpServerPort);
3602     }
3603 #endif
3604 
3605   if (connect(udpSock, (struct sockaddr *) &from, sizeof(from)) < 0)
3606     {
3607       perror("netrek: unable to connect UDP socket after recvfrom()");
3608       close(udpSock);
3609       udpSock = -1;
3610       return -1;
3611     }
3612   return 0;
3613 }
3614 
closeUdpConn(void)3615 int closeUdpConn(void)
3616 {
3617   V_UDPDIAG(("Closing UDP socket\n"));
3618   if (udpSock < 0)
3619     {
3620       fprintf(stderr, "netrek: tried to close a closed UDP socket\n");
3621       return -1;
3622     }
3623   shutdown(udpSock, 2);
3624   close(udpSock);
3625   udpSock = -1;
3626   return 0;
3627 }
3628 
printUdpInfo(void)3629 void printUdpInfo(void)
3630 /* doesn't use UDPDIAG macro because that is for level 2 of udpDebug;
3631  * printUdpInfo applies to level 1 as well */
3632 #define PUDPDIAG(x)      { if (udpDebug) { printf("UDP: "); printf x; }}
3633 {
3634   struct sockaddr_in addr;
3635   socklen_t len;
3636 
3637   len = sizeof(addr);
3638   if (getsockname(udpSock, (struct sockaddr *) &addr, &len) < 0)
3639     {
3640       /* perror("printUdpInfo: getsockname"); */
3641       return;
3642     }
3643 
3644   PUDPDIAG(("LOCAL: addr=0x%x, family=%d, port=%d\n", addr.sin_addr.s_addr,
3645 	    addr.sin_family, ntohs(addr.sin_port)));
3646 
3647   if (getpeername(udpSock, (struct sockaddr *) &addr, &len) < 0)
3648     {
3649       /* perror("printUdpInfo: getpeername"); */
3650       return;
3651     }
3652   PUDPDIAG(("PEER : addr=0x%x, family=%d, port=%d\n", addr.sin_addr.s_addr,
3653 	    addr.sin_family, ntohs(addr.sin_port)));
3654 }
3655 #undef PUDPDIAG
3656 
handleSequence(struct sequence_spacket * packet)3657 void    handleSequence(struct sequence_spacket *packet)
3658 {
3659   static int recent_count = 0, recent_dropped = 0;
3660   LONG    newseq;
3661 
3662   drop_flag = 0;
3663   if (chan != udpSock)
3664     return;					 /* don't pay attention to *
3665 						  * * TCP sequence #s */
3666   udpTotal++;
3667   recent_count++;
3668 
3669   /* update percent display every 256 updates (~50 seconds usually) */
3670   if (!(udpTotal & 0xff))
3671     if (udpWin)
3672       udprefresh(UDP_DROPPED);
3673 
3674   newseq = (LONG) ntohs(packet->sequence);
3675   /* printf("read %d - ", newseq); */
3676 
3677   if (((unsigned short) sequence) > 65000 &&
3678       ((unsigned short) newseq) < 1000)
3679     {
3680       /* we rolled, set newseq = 65536+sequence and accept it */
3681       sequence = ((sequence + 65536) & 0xffff0000) | newseq;
3682     }
3683   else
3684     {
3685       /* adjust newseq and do compare */
3686       newseq |= (sequence & 0xffff0000);
3687 
3688       if (!udpSequenceChk)
3689 	{					 /* put this here so that * *
3690 						  * turning seq check */
3691 	  sequence = newseq;			 /* on and off doesn't make *
3692 						  *
3693 						  * * us think we lost */
3694 	  return;				 /* a whole bunch of packets.
3695 						  *
3696 						  */
3697 	}
3698       if (newseq > sequence)
3699 	{
3700 	  /* accept */
3701 	  if (newseq != sequence + 1)
3702 	    {
3703 	      udpDropped += (newseq - sequence) - 1;
3704 	      udpTotal += (newseq - sequence) - 1;	/* want TOTAL packets
3705 							 *
3706 							 */
3707 	      recent_dropped += (newseq - sequence) - 1;
3708 	      recent_count += (newseq - sequence) - 1;
3709 	      if (udpWin)
3710 		udprefresh(UDP_DROPPED);
3711 	      UDPDIAG(("sequence=%d, newseq=%d, we lost some\n",
3712 		       (int) sequence, (int) newseq));
3713 	    }
3714 	  sequence = newseq;
3715 	  /* S_P2 */
3716 	  if (shortversion == SHORTVERSION && recv_short)
3717 	    {
3718 	      me->p_flags = (me->p_flags & 0xffff00ff) | (unsigned int) packet->flag16 << 8;
3719 	    }
3720 	}
3721       else
3722 	{
3723 	  /* reject */
3724 	  if (packet->type == SP_SC_SEQUENCE)
3725 	    {
3726 	      V_UDPDIAG(("(ignoring repeat %d)\n", (int) newseq));
3727 	    }
3728 	  else
3729 	    {
3730 	      UDPDIAG(("sequence=%d, newseq=%d, ignoring transmission\n",
3731 		       (int) sequence, (int) newseq));
3732 	    }
3733 	  /* the remaining packets will be dropped and we shouldn't count the
3734 	   * * * SP_SEQUENCE packet either */
3735 	  packets_received--;
3736 	  drop_flag = 1;
3737 	}
3738     }
3739   /* printf("newseq %d, sequence %d\n", newseq, sequence); */
3740   if (recent_count > UDP_RECENT_INTR)
3741     {
3742       /* once a minute (at 5 upd/sec), report on how many were dropped */
3743       /* during the last UDP_RECENT_INTR updates                       */
3744       udpRecentDropped = recent_dropped;
3745       recent_count = recent_dropped = 0;
3746       if (udpWin)
3747 	udprefresh(UDP_DROPPED);
3748     }
3749 }
3750 
3751 
3752 #ifdef PACKET_LOG
3753 static int Max_CPS = 0;
3754 static int Max_CPSout = 0;
3755 static time_t Start_Time = 0;
3756 static double s2 = 0;
3757 static int sumpl = 0;
3758 static int numpl = 0;
3759 static int outdata_this_sec = 0;
3760 static double sout2 = 0;
3761 static int sumout = 0;
3762 
3763 /* HW clumsy but who cares ... :-) */
3764 static int vari_sizes[NUM_PACKETS];
3765 static int cp_msg_size;				 /* For CP_S_MESSAGE */
3766 
Log_Packet(char type,int act_size)3767 void Log_Packet(char type, int act_size)
3768 {
3769   static time_t lasttime;
3770   static int data_this_sec;
3771   time_t  this_sec;
3772 
3773   if (log_packets == 0)
3774     return;
3775 
3776   if (type <= 0 && type > NUM_PACKETS)
3777     {
3778       fprintf(stderr, "Attempted to log a bad packet? \n");
3779       return;
3780     }
3781   packet_log[(unsigned) type]++;
3782   /* data_this_sec += handlers[type].size; */
3783   data_this_sec += act_size;			 /* HW */
3784   ALL_BYTES += act_size;			 /* To get all bytes */
3785   if (handlers[(unsigned) type].size == -1)
3786     {						 /* vari packet */
3787       vari_sizes[(unsigned) type] += act_size;
3788     }
3789   this_sec = time(NULL);
3790   if (this_sec != lasttime)
3791     {
3792       lasttime = this_sec;
3793       if (log_packets > 1)
3794 	{
3795 	  fprintf(stdout, "%d %d %d\n", (int) (this_sec - Start_Time), data_this_sec, outdata_this_sec);
3796 	}
3797       if (Start_Time == 0)
3798 	{
3799 	  Start_Time = this_sec;
3800 	}
3801       /* ignore baudage on the first few seconds of reception -- * that's * *
3802        * when we get crushed by the motd being sent */
3803       if (lasttime > Start_Time + 10)
3804 	{
3805 	  if (data_this_sec > Max_CPS)
3806 	    Max_CPS = data_this_sec;
3807 	  if (outdata_this_sec > Max_CPSout)
3808 	    Max_CPSout = outdata_this_sec;
3809 	  sumpl += data_this_sec;
3810 	  s2 += (data_this_sec * data_this_sec);
3811 	  sout2 += outdata_this_sec * outdata_this_sec;
3812 	  sumout += outdata_this_sec;
3813 	  numpl++;
3814 	}
3815       data_this_sec = 0;
3816       outdata_this_sec = 0;
3817     }
3818 }
3819 
Log_OPacket(int type,int size)3820 void Log_OPacket(int type, int size)
3821 {
3822   /* Log Packet will handle the per second resets of this */
3823   if (log_packets == 0)
3824     return;
3825   outpacket_log[type]++;
3826   outdata_this_sec += size;
3827 
3828 #ifdef SHORT_PACKETS
3829   if (type == CP_S_MESSAGE)
3830     cp_msg_size += size;			 /* HW */
3831 #endif
3832 }
3833 
3834 /* print out out the cool information on packet logging */
Dump_Packet_Log_Info(void)3835 void Dump_Packet_Log_Info(void)
3836 {
3837   int     i;
3838   time_t  Now;
3839   int     total_bytes = 0;
3840   int     outtotal_bytes = 0;
3841   int     calc_temp;
3842 
3843   Now = time(NULL);
3844 
3845   printf("Packet Logging Summary:\n");
3846   printf("Start time: %s ", ctime(&Start_Time));
3847   printf(" End time: %s Elapsed play time: %3.2f min\n",
3848 	 ctime(&Now), (float) ((Now - Start_Time) / 60));
3849   printf("Maximum CPS in during normal play: %d bytes per sec\n", Max_CPS);
3850   printf("Standard deviation in: %d\n",
3851 	 (int) sqrt((numpl * s2 - sumpl * sumpl) / (numpl * (numpl - 1))));
3852   printf("Maximum CPS out during normal play: %d bytes per sec\n", Max_CPSout);
3853   printf("Standard deviation out: %d\n",
3854      (int) sqrt((numpl * sout2 - sumout * sumout) / (numpl * (numpl - 1))));
3855 
3856 #ifdef SHORT_PACKETS
3857   /* total_bytes = ALL_BYTES; *//* Hope this works  HW */
3858   for (i = 0; i <= NUM_PACKETS; i++)
3859     {						 /* I think it must be <= */
3860       if (handlers[i].size != -1)
3861 	total_bytes += handlers[i].size * packet_log[i];
3862       else
3863 	total_bytes += vari_sizes[i];
3864     }						 /* The result should be == *
3865 						  *
3866 						  * * ALL_BYTES HW */
3867 #else
3868   for (i = 0; i <= NUM_PACKETS; i++)
3869     {
3870       total_bytes += handlers[i].size * packet_log[i];
3871     }
3872 #endif
3873 
3874   for (i = 0; i <= NUM_SIZES; i++)
3875     {
3876 
3877 #ifdef SHORT_PACKETS
3878       if (handlers[i].size != -1)
3879 	outtotal_bytes += outpacket_log[i] * sizes[i];
3880       else
3881 	outtotal_bytes += cp_msg_size;		 /* HW */
3882 #else
3883       outtotal_bytes += outpacket_log[i] * sizes[i];
3884 #endif
3885     }
3886 
3887   printf("Total bytes received %d, average CPS: %4.1f\n",
3888 	 total_bytes, (float) (total_bytes / (Now - Start_Time)));
3889   printf("Server Packets Summary:\n");
3890   printf("Num #Rcvd    Size   TotlBytes   %%Total\n");
3891   for (i = 0; i <= NUM_PACKETS; i++)
3892     {
3893 
3894 #ifdef SHORT_PACKETS
3895       if (handlers[i].size != -1)
3896 	calc_temp = handlers[i].size * packet_log[i];
3897       else
3898 	calc_temp = vari_sizes[i];
3899 
3900       printf("%3d %5d    %4d   %9d   %3.2f\n",
3901 	     i, packet_log[i], handlers[i].size, calc_temp,
3902 	     (float) (calc_temp * 100 / total_bytes));
3903 #else
3904       calc_temp = handlers[i].size * packet_log[i];
3905       printf("%3d %5d    %4d   %9d   %3.2f\n",
3906 	     i, packet_log[i], handlers[i].size, calc_temp,
3907 	     (float) (calc_temp * 100 / total_bytes));
3908 #endif
3909     }
3910   printf("Total bytes sent %d, average CPS: %4.1f\n",
3911 	 outtotal_bytes, (float) (outtotal_bytes / (Now - Start_Time)));
3912   printf("Client Packets Summary:\n");
3913   printf("Num #Sent    Size   TotlBytes   %%Total\n");
3914   for (i = 0; i <= NUM_SIZES; i++)
3915 #ifdef SHORT_PACKETS
3916     {
3917       if (sizes[i] == -1)
3918 	calc_temp = cp_msg_size;
3919       else
3920 	calc_temp = sizes[i] * outpacket_log[i];
3921       printf("%3d %5d    %4d   %9d   %3.2f\n",
3922 	     i, outpacket_log[i], sizes[i], calc_temp,
3923 	     (float) (calc_temp * 100 / outtotal_bytes));
3924     }
3925 #else
3926     {
3927       calc_temp = sizes[i] * outpacket_log[i];
3928       printf("%3d %5d    %4d   %9d   %3.2f\n",
3929 	     i, outpacket_log[i], sizes[i], calc_temp,
3930 	     (float) (calc_temp * 100 / outtotal_bytes));
3931     }
3932 #endif
3933 }
3934 
print_packet(char * packet,int size)3935 void print_packet(char *packet, int size)
3936 {
3937    int i;                        /* lcv */
3938    unsigned char *data;
3939    int kills, pnum, nplanets;
3940    struct planet_s_spacket *plpacket;
3941 
3942    if(log_packets == 0) return;
3943 
3944    switch ( packet[0] )
3945      {
3946        case SP_MESSAGE:
3947          fprintf(stderr, "\nS->C SP_MESSAGE\t");
3948 	 if (log_packets > 1)
3949 	   fprintf(stderr, "  m_flags=0x%0X, m_recpt=%d, m_from=%d, mesg=\"%s\",",
3950 		   ((struct mesg_spacket *) packet)->m_flags,
3951 		   ((struct mesg_spacket *) packet)->m_recpt,
3952 		   ((struct mesg_spacket *) packet)->m_from,
3953 		   ((struct mesg_spacket *) packet)->mesg );
3954 	 break;
3955        case SP_PLAYER_INFO  :                   /* general player info not */
3956 						/* * elsewhere */
3957 	 fprintf(stderr, "\nS->C SP_PLAYER_INFO\t");
3958 	 if (log_packets > 1)
3959 	   fprintf(stderr, "  pnum=%d, shiptype=%d, team=%d,",
3960 		   ((struct plyr_info_spacket *) packet)->pnum,
3961 		   ((struct plyr_info_spacket *) packet)->shiptype,
3962 		   ((struct plyr_info_spacket *) packet)->team );
3963          break;
3964        case SP_KILLS        :                   /* # kills a player has */
3965 	 fprintf(stderr, "\nS->C SP_KILLS\t");
3966 	 if (log_packets > 1)
3967 	   fprintf(stderr, "  pnum=%d, kills=%u,",
3968 		   ((struct kills_spacket *) packet)->pnum,
3969 		   ntohl(((struct kills_spacket *) packet)->kills) );
3970 	 break;
3971        case SP_PLAYER       :                   /* x,y for player */
3972 	 fprintf(stderr, "\nS->C SP_PLAYER\t");
3973 	 if (log_packets > 1)
3974 	   fprintf(stderr, "  pnum=%d, dir=%u, speed=%d, x=%d, y=%d,",
3975 		   ((struct player_spacket *) packet)->pnum,
3976 		   ((struct player_spacket *) packet)->dir,
3977 		   ((struct player_spacket *) packet)->speed,
3978 		   ntohl(((struct player_spacket *) packet)->x),
3979 		   ntohl(((struct player_spacket *) packet)->y) );
3980 
3981 	 break;
3982        case SP_TORP_INFO    :                   /* torp status */
3983 	 fprintf(stderr, "\nS->C SP_TORP_INFO\t");
3984 	 if (log_packets > 1)
3985 	   fprintf(stderr, "  war=%d, status=%d, tnum=%u,",
3986 		   ((struct torp_info_spacket *) packet)->war,
3987 		   ((struct torp_info_spacket *) packet)->status,
3988 		   ntohs(((struct torp_info_spacket *) packet)->tnum) );
3989 	 break;
3990        case SP_TORP         :                   /* torp location */
3991 	 fprintf(stderr, "\nS->C SP_TORP\t");
3992 	 if (log_packets > 1)
3993 	   fprintf(stderr, "  dir=%d, tnum=%u, x=%u, y=%u,",
3994 		   ((struct torp_spacket *) packet)->dir,
3995 		   ntohs(((struct torp_spacket *) packet)->tnum),
3996 		   ntohl(((struct torp_spacket *) packet)->x),
3997 		   ntohl(((struct torp_spacket *) packet)->y) );
3998 	 break;
3999        case SP_PHASER       :                   /* phaser status and * *
4000 						 * direction */
4001 	 fprintf(stderr, "\nS->C SP_PHASER\t");
4002 	 if (log_packets > 1)
4003 	   fprintf(stderr, "  pnum=%d, status=%d, dir=%u, x=%d, y=%d, target=%d,",
4004 		   ((struct phaser_spacket *) packet)->pnum,
4005 		   ((struct phaser_spacket *) packet)->status,
4006 		   ((struct phaser_spacket *) packet)->dir,
4007 		   ntohl(((struct phaser_spacket *) packet)->x),
4008 		   ntohl(((struct phaser_spacket *) packet)->y),
4009 		   ntohl(((struct phaser_spacket *) packet)->target) );
4010 	 break;
4011        case SP_PLASMA_INFO  :                  /* player login information */
4012 	 fprintf(stderr, "\nS->C SP_PLASMA_INFO\t");
4013 	 if (log_packets > 1)
4014 	   fprintf(stderr, "  war=%d, status=%d  pnum=%u,",
4015 		   ((struct plasma_info_spacket *) packet)->war,
4016 		   ((struct plasma_info_spacket *) packet)->status,
4017 		   ntohs(((struct plasma_info_spacket *) packet)->pnum) );
4018 	 break;
4019        case SP_PLASMA       :                  /* like SP_TORP */
4020 	 fprintf(stderr, "\nS->C SP_PLASMA\t");
4021 	 if (log_packets > 1)
4022 	   fprintf(stderr, "  pnum=%u, x=%d, y=%d,",
4023 		   ntohs(((struct plasma_spacket *) packet)->pnum),
4024 		   ntohl(((struct plasma_spacket *) packet)->x),
4025 		   ntohl(((struct plasma_spacket *) packet)->y) );
4026 	 break;
4027        case SP_WARNING      :                  /* like SP_MESG */
4028 	 fprintf(stderr,"\nS->C SP_WARNING\t");
4029 	 if (log_packets > 1)
4030 	   fprintf(stderr, "  mesg=\"%s\",",
4031 		   ((struct warning_spacket *) packet)->mesg);
4032 	 break;
4033        case SP_MOTD         :                  /* line from .motd screen */
4034 	 fprintf(stderr,"\nS->C SP_MOTD\t");
4035 	 if (log_packets > 1)
4036 	   fprintf(stderr, "  line=\"%s\",",
4037 		   ((struct motd_spacket *) packet)->line);
4038 	 break;
4039        case SP_YOU          :                  /* info on you? */
4040 	 fprintf(stderr, "\nS->C SP_YOU\t");
4041 	 if (log_packets > 1)
4042 	   fprintf(stderr, "  pnum=%d, hostile=%d, swar=%d, armies=%d, flags=0x%0X, damage=%d, shield=%d, fuel=%d, etemp=%u, wtemp=%u, whydead=%u, whodead=%u,",
4043 		   ((struct you_spacket *) packet)->pnum,
4044 		   ((struct you_spacket *) packet)->hostile,
4045 		   ((struct you_spacket *) packet)->swar,
4046 		   ((struct you_spacket *) packet)->armies,
4047 		   ntohs(((struct you_spacket *) packet)->flags),
4048 		   ntohl(((struct you_spacket *) packet)->damage),
4049 		   ntohl(((struct you_spacket *) packet)->shield),
4050 		   ntohl(((struct you_spacket *) packet)->fuel),
4051 		   ntohs(((struct you_spacket *) packet)->etemp),
4052 		   ntohs(((struct you_spacket *) packet)->wtemp),
4053 		   ntohs(((struct you_spacket *) packet)->whydead),
4054 		   ntohs(((struct you_spacket *) packet)->whodead) );
4055 	 break;
4056        case SP_QUEUE        :                  /* estimated loc in queue? */
4057 	 fprintf(stderr, "\nS->C SP_QUEUE\t");
4058 	 if (log_packets > 1)
4059 	   fprintf(stderr, "  pos=%u,",
4060 		   ntohs(((struct queue_spacket *) packet)->pos) );
4061 	 break;
4062        case SP_STATUS       :                  /* galaxy status numbers */
4063 	 fprintf(stderr, "\nS->C SP_STATUS\t");
4064 	 if (log_packets > 1)
4065 	   fprintf(stderr, "  tourn=%d, armsbomb=%u, planets=%u, kills=%u, losses=%u, time=%u, timeprod=%u,",
4066 		   ((struct status_spacket *) packet)->tourn,
4067 		   ntohl(((struct status_spacket *) packet)->armsbomb),
4068 		   ntohl(((struct status_spacket *) packet)->planets),
4069 		   ntohl(((struct status_spacket *) packet)->kills),
4070 		   ntohl(((struct status_spacket *) packet)->losses),
4071 		   ntohl(((struct status_spacket *) packet)->time),
4072 		   ntohl(((struct status_spacket *) packet)->timeprod) );
4073 	 break;
4074        case SP_PLANET       :                  /* planet armies & * *
4075 						* facilities */
4076 	 fprintf(stderr, "\nS->C SP_PLANET\t");
4077 	 if (log_packets > 1)
4078 	   fprintf(stderr, "  pnum=%d, owner=%d, info=%d, flags=0x%0X, armies=%d,",
4079 		   ((struct planet_spacket *) packet)->pnum,
4080 		   ((struct planet_spacket *) packet)->owner,
4081 		   ((struct planet_spacket *) packet)->info,
4082 		   ntohs(((struct planet_spacket *) packet)->flags),
4083 		   ntohl(((struct planet_spacket *) packet)->armies) );
4084 	 break;
4085        case SP_PICKOK       :                  /* your team & ship was * *
4086 						* accepted */
4087 	 fprintf(stderr, "\nS->C SP_PICKOK\t");
4088 	 if (log_packets > 1)
4089 	   fprintf(stderr, "  state=%d,",
4090 		   ((struct pickok_spacket *) packet)-> state );
4091 	 break;
4092        case SP_LOGIN        :                  /* login response */
4093 	 fprintf(stderr, "\nS->C SP_LOGIN\t");
4094 	 if (log_packets > 1)
4095 	   fprintf(stderr, "  accept=%d, flags=0x%0X, keymap=\"%s\",",
4096 		   ((struct login_spacket *) packet)->accept,
4097 		   ntohl(((struct login_spacket *) packet)->flags),
4098 		   ((struct login_spacket *) packet)->keymap );
4099 	 break;
4100        case SP_FLAGS        :                  /* give flags for a player */
4101 	 fprintf(stderr, "\nS->C SP_FLAGS\t");
4102 	 if (log_packets > 1)
4103 	   fprintf(stderr, "  pnum=%d, flags=0x%0X,",
4104 		   ((struct flags_spacket *) packet)->pnum,
4105 		   ntohl(((struct flags_spacket *) packet)->flags) );
4106 	 break;
4107        case SP_MASK         :                  /* tournament mode mask */
4108 	 fprintf(stderr, "\nS->C SP_MASK\t");
4109 	 if (log_packets > 1)
4110 	   fprintf(stderr, "  mask=%d,",
4111 		   ((struct mask_spacket *) packet)->mask );
4112 	 break;
4113        case SP_PSTATUS      :                  /* give status for a player */
4114 	 fprintf(stderr, "\nS->C SP_PSTATUS\t");
4115 	 if (log_packets > 1)
4116 	   fprintf(stderr, "  pnum=%d, status=%d,",
4117 		   ((struct pstatus_spacket *) packet)->pnum,
4118 		   ((struct pstatus_spacket *) packet)->status );
4119 	 break;
4120        case SP_BADVERSION   :                  /* invalid version number */
4121 	 fprintf(stderr, "\nS->C SP_BADVERSION\t");
4122 	 if (log_packets > 1)
4123 	   fprintf(stderr, "  why=%d,",
4124 		   ((struct badversion_spacket *) packet)->why );
4125 	 break;
4126        case SP_HOSTILE      :                  /* hostility settings for a
4127 						* * * player */
4128 	 fprintf(stderr, "\nS->C SP_HOSTILE\t");
4129 	 if (log_packets > 1)
4130 	   fprintf(stderr, "  pnum=%d, war=%d, hostile=%d,",
4131 		   ((struct hostile_spacket *) packet)->pnum,
4132 		   ((struct hostile_spacket *) packet)->war,
4133 		   ((struct hostile_spacket *) packet)->hostile );
4134 	 break;
4135        case SP_STATS        :                  /* a player's statistics */
4136 	 fprintf(stderr, "\nS->C SP_STATS\t");
4137 	 if (log_packets > 1)
4138 	   fprintf(stderr, "  pnum=%d, tkills=%d, tlosses=%d, kills=%d, losses=%d, tticks=%d, tplanets=%d, tarmies=%d, sbkills=%d, sblosses=%d, armies=%d, planets=%d, maxkills=%d, sbmaxkills=%d,",
4139 		   ((struct stats_spacket *) packet)->pnum,
4140 		   ntohl(((struct stats_spacket *) packet)->tkills),
4141 		   ntohl(((struct stats_spacket *) packet)->tlosses),
4142 		   ntohl(((struct stats_spacket *) packet)->kills),
4143 		   ntohl(((struct stats_spacket *) packet)->losses),
4144 		   ntohl(((struct stats_spacket *) packet)->tticks),
4145 		   ntohl(((struct stats_spacket *) packet)->tplanets),
4146 		   ntohl(((struct stats_spacket *) packet)->tarmies),
4147 		   ntohl(((struct stats_spacket *) packet)->sbkills),
4148 		   ntohl(((struct stats_spacket *) packet)->sblosses),
4149 		   ntohl(((struct stats_spacket *) packet)->armies),
4150 		   ntohl(((struct stats_spacket *) packet)->planets),
4151 		   ntohl(((struct stats_spacket *) packet)->maxkills),
4152 		   ntohl(((struct stats_spacket *) packet)->sbmaxkills) );
4153 	 break;
4154        case SP_PL_LOGIN     :                  /* new player logs in */
4155 	 fprintf(stderr, "\nS->C SP_PL_LOGIN\t");
4156 	 if (log_packets > 1)
4157 	   fprintf(stderr, "  pnum=%d, rank=%d, name=\"%s\", monitor=\"%s\", login=\"%s\",",
4158 		   ((struct plyr_login_spacket *) packet)->pnum,
4159 		   ((struct plyr_login_spacket *) packet)->rank,
4160 		   ((struct plyr_login_spacket *) packet)->name,
4161 		   ((struct plyr_login_spacket *) packet)->monitor,
4162 		   ((struct plyr_login_spacket *) packet)->login );
4163 	 break;
4164        case SP_RESERVED     :                  /* for future use */
4165 	 fprintf(stderr, "\nS->C SP_RESERVED\t");
4166          if (log_packets > 1)
4167            {
4168              fprintf(stderr, "  data=");
4169              for( i = 0; i < 16; i++)
4170                fprintf(stderr, "0x%0X ", (unsigned char)((struct reserved_spacket *) packet)->data[i]);
4171              fprintf(stderr, ",");
4172            }
4173 	 break;
4174        case SP_PLANET_LOC   :                  /* planet name, x, y */
4175 	 fprintf(stderr, "\nS->C SP_PLANET_LOC\t");
4176 	 if (log_packets > 1)
4177 	   fprintf(stderr, "  pnum=%d, x=%d, y=%d, name=\"%s\",",
4178 		   ((struct planet_loc_spacket *) packet)->pnum,
4179 		   ntohl(((struct planet_loc_spacket *) packet)->x),
4180 		   ntohl(((struct planet_loc_spacket *) packet)->y),
4181 		   ((struct planet_loc_spacket *) packet)->name );
4182 	 break;
4183 #ifdef INCLUDE_SCAN
4184        /* NOTE: not implemented */
4185        case SP_SCAN         :                  /* ATM: results of player *
4186 						* * scan */
4187 	 fprintf(stderr, "\nS->C SP_SCAN\t");
4188 	 if(log_packets > 1)
4189 	   fprintf(stderr, "not implemented,");
4190 	 break;
4191 #endif
4192        case SP_UDP_REPLY    :                  /* notify client of UDP * *
4193 						* status */
4194 	 fprintf(stderr, "\nS->C SP_UDP_REPLY\t");
4195 	 if (log_packets > 1)
4196 	   fprintf(stderr, "  reply=%d, port=%d,",
4197 		   ((struct udp_reply_spacket *) packet)->reply,
4198 		   ntohl(((struct udp_reply_spacket *) packet)->port) );
4199 	 break;
4200        case SP_SEQUENCE     :                  /* sequence # packet */
4201 	 fprintf(stderr, "\nS->C SP_SEQUENCE\t");
4202 	 if (log_packets > 1)
4203 	   fprintf(stderr, "  flag16=0x%0X, sequence=%u,",
4204 		   ((struct sequence_spacket *) packet)->flag16,
4205 		   ntohs(((struct sequence_spacket *) packet)->sequence) );
4206 	 break;
4207        case SP_SC_SEQUENCE  :                  /* this trans is * *
4208 						* semi-critical info */
4209 	 fprintf(stderr, "\nS->C SP_SC_SEQUENCE\t");
4210 	 if (log_packets > 1)
4211 	   fprintf(stderr, "  sequence=%u,",
4212 		   ntohs(((struct sc_sequence_spacket *) packet)->sequence) );
4213 	 break;
4214 
4215 #ifdef RSA
4216        case SP_RSA_KEY      :                  /* handles binary * *
4217 						* verification */
4218 	 fprintf(stderr, "\nS->C SP_RSA_KEY\t");
4219 	 if(log_packets > 1)
4220 	   {
4221 	     fprintf(stderr, "  data=");
4222 	     for(i = 0; i < KEY_SIZE; i++)
4223 	       fprintf(stderr, "0x%0X ",((struct rsa_key_spacket *) packet)->data[i]);
4224 	     fprintf(stderr, ",");
4225 	   }
4226 	 break;
4227 #endif
4228        case SP_GENERIC_32   :
4229 	 fprintf(stderr, "\nS->C SP_GENERIC_32\t");
4230 	 if (log_packets > 1)
4231 	   switch (((struct generic_32_spacket *)packet)->version) {
4232 	   case 0x60+GENERIC_32_VERSION_A:
4233 	     fprintf(stderr, "  version=%c, repair_time=%d, pl_orbit=%d,",
4234 		     ((struct generic_32_spacket_a *) packet)->version,
4235 		     ((struct generic_32_spacket_a *) packet)->repair_time,
4236 		     ((struct generic_32_spacket_a *) packet)->pl_orbit);
4237 	     break;
4238 	   case 0x60+GENERIC_32_VERSION_B:
4239 	     fprintf(stderr, "  version=%c, repair_time=%d, pl_orbit=%d, gameup=0x%x, tourn_teams=%d, tourn_age=%d, tourn_age_units=%c, tourn_remain=%d, tourn_remain_units=%c, starbase_remain=%d, team_remain=%d,",
4240 		     ((struct generic_32_spacket_b *) packet)->version,
4241 		     ntohs(((struct generic_32_spacket_b *) packet)->repair_time),
4242 		     ((struct generic_32_spacket_b *) packet)->pl_orbit,
4243 		     ntohs(((struct generic_32_spacket_b *) packet)->gameup),
4244 		     ((struct generic_32_spacket_b *) packet)->tournament_teams,
4245 		     ((struct generic_32_spacket_b *) packet)->tournament_age,
4246 		     ((struct generic_32_spacket_b *) packet)->tournament_age_units,
4247 		     ((struct generic_32_spacket_b *) packet)->tournament_remain,
4248 		     ((struct generic_32_spacket_b *) packet)->tournament_remain_units,
4249 		     ((struct generic_32_spacket_b *) packet)->starbase_remain,
4250 		     ((struct generic_32_spacket_b *) packet)->team_remain );
4251 	     break;
4252 	   default:
4253 	     fprintf(stderr, "  version=0x%x (unknown)", ((struct generic_32_spacket *)packet)->version);
4254 	   }
4255 	 break;
4256 
4257        case SP_SHIP_CAP     :                   /* Handles server ship mods */
4258 	 fprintf(stderr, "\nS->C SP_SHIP_CAP\t");
4259 	 if (log_packets > 1)
4260 	   fprintf(stderr, "  operation=%d, s_type=%u, s_torpspeed=%u, s_phaserrange=%u, s_maxspeed=%d, s_maxfuel=%d, s_maxshield=%d, s_maxdamage=%d, s_maxwpntemp=%d, s_maxegntemp=%d, s_width=%u, s_height=%d, s_maxarmies=%d, s_letter=%d, s_name=\"%s\", s_desig1=%c, s_desig2=%c, s_bitmap=%u,",
4261 		   ((struct ship_cap_spacket *) packet)->operation,
4262 		   ntohs(((struct ship_cap_spacket *) packet)->s_type),
4263 		   ntohs(((struct ship_cap_spacket *) packet)->s_torpspeed),
4264 		   ntohs(((struct ship_cap_spacket *) packet)->s_phaserrange),
4265 		   ((struct ship_cap_spacket *) packet)->s_maxspeed,
4266 		   ((struct ship_cap_spacket *) packet)->s_maxfuel,
4267 		   ((struct ship_cap_spacket *) packet)->s_maxshield,
4268 		   ((struct ship_cap_spacket *) packet)->s_maxdamage,
4269 		   ((struct ship_cap_spacket *) packet)->s_maxwpntemp,
4270 		   ((struct ship_cap_spacket *) packet)->s_maxegntemp,
4271 		   ntohs(((struct ship_cap_spacket *) packet)->s_width),
4272 		   ntohs(((struct ship_cap_spacket *) packet)->s_height),
4273 		   ntohs(((struct ship_cap_spacket *) packet)->s_maxarmies),
4274 		   ((struct ship_cap_spacket *) packet)->s_letter,
4275 		   ((struct ship_cap_spacket *) packet)->s_name,
4276 		   ((struct ship_cap_spacket *) packet)->s_desig1,
4277 		   ((struct ship_cap_spacket *) packet)->s_desig2,
4278 		   ntohs(((struct ship_cap_spacket *) packet)->s_bitmap) );
4279 
4280 	 break;
4281 #ifdef SHORT_PACKETS
4282        case SP_S_REPLY      :                  /* reply to send-short * *
4283 						* request */
4284 	 fprintf(stderr, "\nS->C SP_S_REPLY\t");
4285 	 if (log_packets > 1)
4286 	   fprintf(stderr,"  repl=%d, windside=%u, gwidth=%d,",
4287 		   ((struct shortreply_spacket *) packet)->repl,
4288 		   ntohs(((struct shortreply_spacket *) packet)->winside),
4289 		   ntohl(((struct shortreply_spacket *) packet)->gwidth) );
4290 	 break;
4291        case SP_S_MESSAGE    :                  /* var. Message Packet */
4292 	 fprintf(stderr, "\nS->C SP_S_MESSAGE\t");
4293 	 if (log_packets > 1)
4294 
4295 	   fprintf(stderr, "  m_flags=0x%0X, m_recpt=%u, m_from=%u, length=%u, mesg=\"%s\",",
4296 	    	   ((struct mesg_s_spacket *) packet)->m_flags,
4297 		   ((struct mesg_s_spacket *) packet)->m_recpt,
4298 		   ((struct mesg_s_spacket *) packet)->m_from,
4299 		   ((struct mesg_s_spacket *) packet)->length,
4300 		   &( ((struct mesg_s_spacket *) packet)->mesg ) );
4301 	 break;
4302        case SP_S_WARNING    :                  /* Warnings with 4  Bytes */
4303 	 fprintf(stderr, "\nS->C SP_S_WARNING\t");
4304 	 if (log_packets > 1)
4305 	   fprintf(stderr, "  whichmessage=%u, argument=%d, argument2=%d,",
4306 		   ((struct warning_s_spacket *) packet)->whichmessage,
4307 		   ((struct warning_s_spacket *) packet)->argument,
4308 		   ((struct warning_s_spacket *) packet)->argument2 );
4309 	 break;
4310        case SP_S_YOU        :                  /* hostile,armies,whydead,etc
4311 						* * * .. */
4312 	 fprintf(stderr, "\nS->C SP_S_YOU\t");
4313 	 if (log_packets > 1)
4314 	   fprintf(stderr, "  pnum=%d, hostile=%d, swar=%d, armies=%d, whydead=%d, whodead=%d, flags=0x%0X,",
4315 		   ((struct youshort_spacket *) packet)->pnum,
4316 		   ((struct youshort_spacket *) packet)->hostile,
4317 		   ((struct youshort_spacket *) packet)->swar,
4318 		   ((struct youshort_spacket *) packet)->armies,
4319 		   ((struct youshort_spacket *) packet)->whydead,
4320 		   ((struct youshort_spacket *) packet)->whodead,
4321 		   ntohl(((struct youshort_spacket *) packet)->flags) );
4322 	 break;
4323        case SP_S_YOU_SS     :                  /* your ship status */
4324 	 fprintf(stderr, "\nS->C SP_S_YOU_SS\t");
4325 	 if (log_packets > 1)
4326 	   fprintf(stderr, "  ddamage=%u, shield=%u, fuel=%u, etemp=%u, wtemp=%u,",
4327 		   ntohs(((struct youss_spacket *) packet)->damage),
4328 		   ntohs(((struct youss_spacket *) packet)->shield),
4329 		   ntohs(((struct youss_spacket *) packet)->fuel),
4330 		   ntohs(((struct youss_spacket *) packet)->etemp),
4331 		   ntohs(((struct youss_spacket *) packet)->wtemp) );
4332 	 break;
4333        case SP_S_PLAYER     :                  /* variable length player *
4334 						* * packet */
4335 	 fprintf(stderr, "\nS->C SP_S_PLAYER\t");
4336 	 if (log_packets > 1)
4337 	   fprintf(stderr, "  packets=%d, dir=%u, speed=%d, x=%d, y=%d,",
4338 		   ((struct player_s_spacket *) packet)->packets,
4339 		   ntohl(((struct player_s_spacket *) packet)->dir),
4340 		   ((struct player_s_spacket *) packet)->speed,
4341 		   ntohl(((struct player_s_spacket *) packet)->x),
4342 		   ntohl(((struct player_s_spacket *) packet)->y) );
4343 	 break;
4344 #endif
4345 
4346 #ifdef PING
4347        case SP_PING         :                  /* ping packet */
4348 	 fprintf(stderr, "\nS->C SP_PING\t");
4349 	 if (log_packets > 1)
4350 	   fprintf(stderr, "  number=%u, lag=%u, tloss_sc=%u, tloss_cs=%u, iloss_sc=%u, iloss_cs=%u,",
4351 		   ((struct ping_spacket *) packet)->number,
4352 		   ((struct ping_spacket *) packet)->lag,
4353 		   ((struct ping_spacket *) packet)->tloss_sc,
4354 		   ((struct ping_spacket *) packet)->tloss_cs,
4355 		   ((struct ping_spacket *) packet)->iloss_sc,
4356 		   ((struct ping_spacket *) packet)->iloss_cs );
4357 	 break;
4358 #endif
4359 #ifdef FEATURE_PACKETS
4360        case SP_FEATURE      :
4361 	 fprintf(stderr, "\nS->C SP_FEATURE\t");
4362 	 if (log_packets > 1)
4363 	   fprintf(stderr, "  feature_type=%c, arg1=%d, arg2=%d, value=%d, name=\"%s\",",
4364 		   ((struct feature_cpacket *) packet)->feature_type,
4365 		   ((struct feature_cpacket *) packet)->arg1,
4366 		   ((struct feature_cpacket *) packet)->arg2,
4367 		   ntohl(((struct feature_cpacket *) packet)->value),
4368 		   ((struct feature_cpacket *) packet)->name );
4369 	 break;
4370 #endif
4371        case SP_RANK         :
4372 	 fprintf(stderr, "\nS->C SP_RANK\t");
4373 	 if (log_packets > 1)
4374 	   fprintf(stderr, "  rnum=%d, rmax=%d, name=\"%s\", hours=%d, ratings=%d, offense=%d, cname=\"%s\"",
4375 		   ((struct rank_spacket *) packet)->rnum,
4376 		   ((struct rank_spacket *) packet)->rmax,
4377 		   ((struct rank_spacket *) packet)->name,
4378 		   ntohl(((struct rank_spacket *) packet)->hours),
4379 		   ntohl(((struct rank_spacket *) packet)->ratings),
4380 		   ntohl(((struct rank_spacket *) packet)->offense),
4381 		   ((struct rank_spacket *) packet)->cname );
4382 	 break;
4383        case SP_LTD          :
4384          fprintf(stderr, "\nS->C SP_LTD\t");
4385          if (log_packets > 2) {
4386            struct ltd_spacket *lp = (struct ltd_spacket *) packet;
4387            fprintf(stderr,
4388                    "  version='%c', "
4389                    "kt=%d, "
4390                    "kmax=%d/100, "
4391                    "k1=%d, "
4392                    "k1p=%d, "
4393                    "k1c=%d, "
4394                    "k2=%d, "
4395                    "k2p=%d, "
4396                    "k2c=%d, "
4397                    "kbp=%d, "
4398                    "kbt=%d, "
4399                    "kbs=%d, "
4400                    "dt=%d, "
4401                    "dpc=%d, "
4402                    "dcc=%d, "
4403                    "ddc=%d, "
4404                    "dbp=%d, "
4405                    "dbt=%d, "
4406                    "dbs=%d, "
4407                    "acc=%d, "
4408                    "ptt=%d, "
4409                    "pdt=%d, "
4410                    "bpt=%d, "
4411                    "bp8=%d, "
4412                    "bpc=%d, "
4413                    "bat=%d, "
4414                    "ba8=%d, "
4415                    "bac=%d, "
4416                    "oat=%d, "
4417                    "odc=%d, "
4418                    "occ=%d, "
4419                    "opc=%d, "
4420                    "ogc=%d, "
4421                    "oec=%d, "
4422                    "olc=%d, "
4423                    "osba=%d, "
4424                    "ofc=%d, "
4425                    "ofa=%d, "
4426                    "at=%d, "
4427                    "aa=%d, "
4428                    "ar=%d, "
4429                    "af=%d, "
4430                    "ak=%d, "
4431                    "ct=%d, "
4432                    "cp=%d, "
4433                    "cc=%d, "
4434                    "ca=%d, "
4435                    "cr=%d, "
4436                    "cf=%d, "
4437                    "tt=%d, "
4438                    "tyel=%d, "
4439                    "tred=%d, "
4440                    "tz0=%d, "
4441                    "tz1=%d, "
4442                    "tz2=%d, "
4443                    "tz3=%d, "
4444                    "tz4=%d, "
4445                    "tz5=%d, "
4446                    "tz6=%d, "
4447                    "tz7=%d, "
4448                    "tpc=%d, "
4449                    "tcc=%d, "
4450                    "tr=%d, "
4451                    "dr=%d, "
4452                    "wpf=%d, "
4453                    "wph=%d, "
4454                    "wpdi=%d, "
4455                    "wpdt=%d, "
4456                    "wtf=%d, "
4457                    "wth=%d, "
4458                    "wtd=%d, "
4459                    "wts=%d, "
4460                    "wtw=%d, "
4461                    "wtdi=%d, "
4462                    "wtdt=%d, "
4463                    "wsf=%d, "
4464                    "wsh=%d, "
4465                    "wsp=%d, "
4466                    "wsw=%d, "
4467                    "wsdi=%d, "
4468                    "wsdt=%d, \n",
4469                    lp->version,
4470                    ntohl(lp->kt),
4471                    ntohl(lp->kmax),
4472                    ntohl(lp->k1),
4473                    ntohl(lp->k1p),
4474                    ntohl(lp->k1c),
4475                    ntohl(lp->k2),
4476                    ntohl(lp->k2p),
4477                    ntohl(lp->k2c),
4478                    ntohl(lp->kbp),
4479                    ntohl(lp->kbt),
4480                    ntohl(lp->kbs),
4481                    ntohl(lp->dt),
4482                    ntohl(lp->dpc),
4483                    ntohl(lp->dcc),
4484                    ntohl(lp->ddc),
4485                    ntohl(lp->dbp),
4486                    ntohl(lp->dbt),
4487                    ntohl(lp->dbs),
4488                    ntohl(lp->acc),
4489                    ntohl(lp->ptt),
4490                    ntohl(lp->pdt),
4491                    ntohl(lp->bpt),
4492                    ntohl(lp->bp8),
4493                    ntohl(lp->bpc),
4494                    ntohl(lp->bat),
4495                    ntohl(lp->ba8),
4496                    ntohl(lp->bac),
4497                    ntohl(lp->oat),
4498                    ntohl(lp->odc),
4499                    ntohl(lp->occ),
4500                    ntohl(lp->opc),
4501                    ntohl(lp->ogc),
4502                    ntohl(lp->oec),
4503                    ntohl(lp->olc),
4504                    ntohl(lp->osba),
4505                    ntohl(lp->ofc),
4506                    ntohl(lp->ofa),
4507                    ntohl(lp->at),
4508                    ntohl(lp->aa),
4509                    ntohl(lp->ar),
4510                    ntohl(lp->af),
4511                    ntohl(lp->ak),
4512                    ntohl(lp->ct),
4513                    ntohl(lp->cp),
4514                    ntohl(lp->cc),
4515                    ntohl(lp->ca),
4516                    ntohl(lp->cr),
4517                    ntohl(lp->cf),
4518                    ntohl(lp->tt),
4519                    ntohl(lp->tyel),
4520                    ntohl(lp->tred),
4521                    ntohl(lp->tz0),
4522                    ntohl(lp->tz1),
4523                    ntohl(lp->tz2),
4524                    ntohl(lp->tz3),
4525                    ntohl(lp->tz4),
4526                    ntohl(lp->tz5),
4527                    ntohl(lp->tz6),
4528                    ntohl(lp->tz7),
4529                    ntohl(lp->tpc),
4530                    ntohl(lp->tcc),
4531                    ntohl(lp->tr),
4532                    ntohl(lp->dr),
4533                    ntohl(lp->wpf),
4534                    ntohl(lp->wph),
4535                    ntohl(lp->wpdi),
4536                    ntohl(lp->wpdt),
4537                    ntohl(lp->wtf),
4538                    ntohl(lp->wth),
4539                    ntohl(lp->wtd),
4540                    ntohl(lp->wts),
4541                    ntohl(lp->wtw),
4542                    ntohl(lp->wtdi),
4543                    ntohl(lp->wtdt),
4544                    ntohl(lp->wsf),
4545                    ntohl(lp->wsh),
4546                    ntohl(lp->wsp),
4547                    ntohl(lp->wsw),
4548                    ntohl(lp->wsdi),
4549                    ntohl(lp->wsdt)
4550                    );
4551          }
4552          break;
4553 #ifdef SHORT_PACKETS
4554        case SP_S_TORP       :                  /* variable length torp * *
4555 						* packet */
4556 	 fprintf(stderr, "\nS->C SP_S_TORP\t");
4557 	 if (log_packets > 1)
4558 	   print_sp_s_torp(packet, 1);
4559 	 break;
4560        case SP_S_TORP_INFO  :                  /* SP_S_TORP with TorpInfo */
4561 	 fprintf(stderr, "\nS->C SP_S_TORP_INFO\t");
4562 	 if (log_packets > 1)         /* struct built by hand in handleVTorp */
4563 	   print_sp_s_torp(packet, 3);
4564 	 break;
4565        case SP_S_8_TORP     :                  /* optimized SP_S_TORP */
4566 	 fprintf(stderr, "\nS->C SP_S_8_TORP\t");
4567 	 if (log_packets > 1)
4568 	   print_sp_s_torp(packet, 2);
4569 	 break;
4570        case SP_S_PLANET     :                  /* see SP_PLANET */
4571 	 fprintf(stderr, "\nS->C SP_S_PLANET\t");
4572 	 if (log_packets > 1)
4573 	   {
4574 	     plpacket = (struct planet_s_spacket *) &packet[2];
4575 	     nplanets = packet[1];
4576              fprintf(stderr, "nplanets = %d, ", nplanets);
4577              for(i = 0; i < nplanets; i++, plpacket++ )
4578 	       fprintf(stderr,
4579 		       "pnum = %d, pl_owner = %d, info = %d, flags = %d, armies = %d ",
4580 		       plpacket->pnum,
4581 		       plpacket->owner,
4582 		       plpacket->info,
4583 		       plpacket->armies,
4584 		       ntohs(plpacket->flags) );
4585 	   }
4586 	 fprintf(stderr,"\n");
4587 	 break;
4588 
4589        /* S_P2 */
4590        case SP_S_SEQUENCE   :                  /* SP_SEQUENCE for * *
4591 						* compressed packets */
4592 	 fprintf(stderr, "\nS->C SP_S_SEQUENCE\t");
4593 	 if (log_packets > 1)
4594 	   fprintf(stderr, "  No struct defined,");
4595 	 break;
4596        case SP_S_PHASER     :                  /* see struct */
4597 	 fprintf(stderr, "\nS->C SP_S_PHASER\t");
4598 	 if (log_packets > 1)
4599 	   fprintf(stderr, "  status=%d, pnum=%d, target=%d, dir=%d, x=%d, y=%d",
4600 		   ((((struct phaser_s_spacket *) packet)->status) & 0x0f),
4601 		   ((((struct phaser_s_spacket *) packet)->pnum) & 0x3f),
4602 		   ((struct phaser_s_spacket *) packet)->target,
4603 		   ((struct phaser_s_spacket *) packet)->dir,
4604 		   (SCALE * (ntohs(((struct phaser_s_spacket*) packet)->x))),
4605 		   (SCALE * (ntohs(((struct phaser_s_spacket*) packet)->y))) );
4606 	 break;
4607        case SP_S_KILLS      :                  /* # of kills player have */
4608 	 fprintf(stderr, "\nS->C SP_S_KILLS\t");
4609 	 if (log_packets > 1)
4610 	   {
4611 	     fprintf(stderr, "  pnum=%d, ",
4612 		      (unsigned char) packet[1]);
4613              data = (unsigned char *) &packet[2];
4614              for (i = 0; i < (unsigned) packet[1]; i++)
4615 	       {
4616 		 kills = (unsigned short) *data++;
4617                  kills |= (unsigned short) ((*data & 0x03) << 8);
4618                  pnum = (unsigned char) *data++ >> 2;
4619                  fprintf(stderr, "pnum = %d, kills = %d ",pnum, kills);
4620 	       }
4621 	   }
4622 	 fprintf(stderr,"\n");
4623 	 break;
4624        case SP_S_STATS      :                  /* see SP_STATS */
4625 	 fprintf(stderr, "\nS->C SP_S_STATS\t");
4626 	 if (log_packets > 1)
4627 	   fprintf(stderr, "  pnum=%d, tplanets=%d, tkills=%d, tlosses=%d, kills=%d, losses=%d, tticks=%d, tarmies=%d, sbkills=%d, sblosses=%d, armies=%d, planets=%d, maxkills=%d, sbmaxkills=%d,",
4628 		   ((struct stats_spacket *) packet)->pnum,
4629 		   ntohs(((struct stats_spacket *) packet)->tplanets),
4630 		   ntohs(((struct stats_spacket *) packet)->tkills),
4631 		   ntohs(((struct stats_spacket *) packet)->tlosses),
4632 		   ntohs(((struct stats_spacket *) packet)->kills),
4633 		   ntohs(((struct stats_spacket *) packet)->losses),
4634 		   ntohl(((struct stats_spacket *) packet)->tticks),
4635 		   ntohl(((struct stats_spacket *) packet)->tarmies),
4636 		   ntohs(((struct stats_spacket *) packet)->sbkills),
4637 		   ntohs(((struct stats_spacket *) packet)->sblosses),
4638 		   ntohs(((struct stats_spacket *) packet)->armies),
4639 		   ntohs(((struct stats_spacket *) packet)->planets),
4640 		   ntohl(((struct stats_spacket *) packet)->maxkills),
4641 		   ntohl(((struct stats_spacket *) packet)->sbmaxkills) );
4642 	 break;
4643 #endif
4644      default:
4645        fprintf(stderr, "\nS->C UNKNOWN\t");
4646        if(log_packets > 1)
4647 	 fprintf(stderr, "  type=%d,",packet[0]);
4648      }
4649 
4650 #ifdef nodef /* #ifdef SHORT_PACKETS */
4651    switch( *((char *) packet) )
4652      {
4653        /* variable length packets */
4654        case VPLAYER_SIZE    :
4655 	 fprintf(stderr, "\nS->C VPLAYER_SIZE\t");
4656 	 if (log_packets > 1)
4657 	   fprintf(stderr, "  No struct defined, same enum value as SP_PLAYER,");
4658 	 break;
4659        case SHORTVERSION    :                   /* other number blocks, like
4660 						 * * * UDP Version */
4661 	 fprintf(stderr, "\nS->C SHORTVERSION\t");
4662 	 if (log_packets > 1)
4663 	   fprintf(stderr, "  No struct defined, same enum value as SP_MOTD,");
4664 	 break;
4665        case OLDSHORTVERSION :                   /* S_P2 */
4666 	 fprintf(stderr, "\nS->C OLDSHORTVERSION\t");
4667 	 if (log_packets > 1)
4668 	   fprintf(stderr, "  No struct defined, same enum value as SP_WARNING,");
4669 	 break;
4670      }
4671 #endif
4672 
4673 }
4674 
4675 
print_opacket(char * packet,int size)4676 void print_opacket(char *packet, int size)
4677 {
4678   int i;  /* lcv */
4679 
4680   switch(packet[0])
4681     {
4682       /* packets sent from remote client to xtrek server */
4683     case CP_MESSAGE      :                    /* send a message */
4684       fprintf(stderr, "\nC->S CP_MESSAGE\t");
4685       if (log_packets > 1)
4686 	fprintf(stderr, "  group=%d, indiv=%d, mesg=\"%s\",",
4687 		((struct mesg_cpacket *) packet)->group,
4688 		((struct mesg_cpacket *) packet)->indiv,
4689 		((struct mesg_cpacket *) packet)->mesg );
4690       break;
4691     case CP_SPEED        :                    /* set speed */
4692       fprintf(stderr, "\nC->S CP_SPEED\t");
4693       if (log_packets > 1)
4694 	fprintf(stderr, "  speed=%d,",
4695 		((struct speed_cpacket *) packet)->speed );
4696       break;
4697     case CP_DIRECTION    :                    /* change direction */
4698       fprintf(stderr, "\nC->S CP_DIRECTION\t");
4699       if (log_packets > 1)
4700 	fprintf(stderr, "  dir=%u,",
4701 		((struct dir_cpacket *) packet)->dir );
4702       break;
4703     case CP_PHASER       :                    /* phaser in a direction */
4704       fprintf(stderr, "\nC->S CP_PHASER\t");
4705       if (log_packets > 1)
4706 	fprintf(stderr, "  dir=%u,",
4707 		((struct phaser_cpacket *) packet)-> dir );
4708       break;
4709     case CP_PLASMA       :                    /* plasma (in a direction) */
4710       fprintf(stderr, "\nC->S CP_PLAMSA\t");
4711       if (log_packets > 1)
4712 	fprintf(stderr, "  dir=%u,",
4713 		((struct plasma_cpacket *) packet)->dir );
4714       break;
4715     case CP_TORP         :                    /* fire torp in a direction */
4716       fprintf(stderr, "\nC->S CP_TORP\t");
4717       if (log_packets > 1)
4718 	fprintf(stderr, "  dir=%u,",
4719 		((struct torp_cpacket *) packet)->dir );
4720       break;
4721     case CP_QUIT         :                    /* self destruct */
4722       fprintf(stderr, "\nC->S CP_QUIT\t");
4723       if (log_packets > 1)
4724 	fprintf(stderr, "  no args,");
4725       break;
4726     case CP_LOGIN        :                    /* log in (name, password) */
4727       fprintf(stderr, "\nC->S CP_LOGIN\t");
4728       if (log_packets > 1)
4729 	fprintf(stderr, "  query=%d, name=\"%s\", password=\"%s\", login=\"%s\",",
4730 		((struct login_cpacket *) packet)->query,
4731 		((struct login_cpacket *) packet)->name,
4732 		((struct login_cpacket *) packet)->password,
4733 		((struct login_cpacket *) packet)->login );
4734       break;
4735     case CP_OUTFIT       :                    /* outfit to new ship */
4736       fprintf(stderr, "\nC->S CP_OUTFIT\t");
4737       if (log_packets > 1)
4738 	fprintf(stderr, "  team=%d, ship=%d,",
4739 		((struct outfit_cpacket *) packet)->team,
4740 		((struct outfit_cpacket *) packet)->ship );
4741       break;
4742     case CP_WAR          :                    /* change war status */
4743       fprintf(stderr, "\nC->S CP_WAR\t");
4744       if (log_packets > 1)
4745 	fprintf(stderr, "  newmask=0x%0X,",
4746 		((struct war_cpacket *) packet)->newmask );
4747       break;
4748     case CP_PRACTR       :                    /* create practice robot? */
4749       fprintf(stderr, "\nC->S CP_PRACTR\t");
4750       if (log_packets > 1)
4751 	fprintf(stderr, "  no args,");
4752       break;
4753     case CP_SHIELD       :                    /* raise/lower sheilds */
4754       fprintf(stderr, "\nC->S CP_SHIELD\t");
4755       if (log_packets > 1)
4756 	fprintf(stderr, "  state=%d,",
4757 		((struct shield_cpacket *) packet)->state );
4758       break;
4759     case CP_REPAIR       :                    /* enter repair mode */
4760       fprintf(stderr, "\nC->S CP_REPAIR\t");
4761       if (log_packets > 1)
4762 	fprintf(stderr, "  state=%d,",
4763 		((struct repair_cpacket *) packet)-> state );
4764       break;
4765     case CP_ORBIT        :                    /* orbit planet/starbase */
4766       fprintf(stderr, "\nC->S CP_ORBIT\t");
4767       if (log_packets > 1)
4768 	fprintf(stderr, "  state=%d,",
4769 		((struct orbit_cpacket *) packet)->state );
4770       break;
4771     case CP_PLANLOCK     :                    /* lock on planet */
4772       fprintf(stderr, "\nC->S CP_PLANLOCK\t");
4773       if (log_packets > 1)
4774 	fprintf(stderr, "  pnum = %d,",
4775 		((struct planlock_cpacket *) packet)->pnum );
4776       break;
4777     case CP_PLAYLOCK     :                    /* lock on player */
4778       fprintf(stderr, "\nC->S CP_PLAYLOCK\t");
4779       if (log_packets > 1)
4780 	fprintf(stderr, "  pnum=%d,",
4781 		((struct playlock_cpacket *) packet)->pnum );
4782       break;
4783     case CP_BOMB         :                    /* bomb a planet */
4784       fprintf(stderr, "\nC->S CP_BOMB\t");
4785       if (log_packets > 1)
4786 	fprintf(stderr, "  state=%d,",
4787 		((struct bomb_cpacket *) packet)->state );
4788       break;
4789     case CP_BEAM         :                    /* beam armies up/down */
4790       fprintf(stderr, "\nC->S CP_BEAM\t");
4791       if (log_packets > 1)
4792 	fprintf(stderr, "  state=%d,",
4793 		((struct beam_cpacket *) packet)->state );
4794       break;
4795     case CP_CLOAK        :                    /* cloak on/off */
4796       fprintf(stderr, "\nC->S CP_CLOAK\t");
4797       if (log_packets > 1)
4798 	fprintf(stderr, "  state=%d,",
4799 		((struct cloak_cpacket *) packet)->state );
4800       break;
4801     case CP_DET_TORPS    :                    /* detonate enemy torps */
4802       fprintf(stderr, "\nC->S CP_DET_TORPS\t");
4803       if (log_packets > 1)
4804 	fprintf(stderr, "  no args,");
4805       break;
4806     case CP_DET_MYTORP   :                    /* detonate one of my torps */
4807       fprintf(stderr, "\nC->S CP_DET_MYTORP\t");
4808       if (log_packets > 1)
4809 	fprintf(stderr, "  tnum=%u,",
4810 		ntohs(((struct det_mytorp_cpacket *) packet)->tnum) );
4811       break;
4812     case CP_COPILOT      :                    /* toggle copilot mode */
4813       fprintf(stderr, "\nC->S CP_COPILOT\t");
4814       if (log_packets > 1)
4815 	fprintf(stderr, "  state=%d,",
4816                 ((struct copilot_cpacket *) packet)->state );
4817       break;
4818     case CP_REFIT        :                    /* refit to different ship *
4819 					       *
4820 					       * * type */
4821       fprintf(stderr, "\nC->S CP_REFIT\t");
4822       if (log_packets > 1)
4823 	fprintf(stderr, "  ship=%d,",
4824 		((struct refit_cpacket *) packet)->ship );
4825       break;
4826     case CP_TRACTOR      :                    /* tractor on/off */
4827       fprintf(stderr, "\nC->S CP_TRACTOR\t");
4828       if (log_packets > 1)
4829 	fprintf(stderr, "  state=%d, pnum=%d,",
4830 		((struct tractor_cpacket *) packet)->state,
4831 		((struct tractor_cpacket *) packet)->pnum );
4832       break;
4833     case CP_REPRESS      :                    /* pressor on/off */
4834       fprintf(stderr, "\nC->S CP_REPRESS\t");
4835       if (log_packets > 1)
4836 	fprintf(stderr, "  state=%d, pnum=%d,",
4837 		((struct repress_cpacket *) packet)->state,
4838 		((struct repress_cpacket *) packet)->pnum );
4839       break;
4840     case CP_COUP         :                    /* coup home planet */
4841       fprintf(stderr, "\nC->S CP_COUP\t");
4842       if (log_packets > 1)
4843 	fprintf(stderr, "  no args,");
4844       break;
4845     case CP_SOCKET       :                    /* new socket for * *
4846 				               * reconnection */
4847       fprintf(stderr, "\nC->S CP_SOCKET\t");
4848       if (log_packets > 1)
4849 	fprintf(stderr, "  version=%d, udp_version=%d\n, socket=%u,",
4850 		((struct socket_cpacket *) packet)->version,
4851 		((struct socket_cpacket *) packet)->udp_version,
4852 		ntohl(((struct socket_cpacket *) packet)->socket)  );
4853       break;
4854     case CP_OPTIONS      :                    /* send my options to be * *
4855 					       * saved */
4856       fprintf(stderr, "\nC->S CP_OPTIONS\t");
4857       if (log_packets > 1)
4858 	fprintf(stderr, "  flags=0x%0X, keymap=\"%s\",",
4859 		ntohl(((struct options_cpacket *) packet)->flags),
4860 		((struct options_cpacket *) packet)->keymap );
4861       break;
4862     case CP_BYE          :                    /* I'm done! */
4863       fprintf(stderr, "\nC->S CP_BYE\t");
4864       if (log_packets > 1)
4865 	fprintf(stderr, "  no args,");
4866       break;
4867     case CP_DOCKPERM     :                    /* set docking permissions */
4868       fprintf(stderr, "\nC->S CP_DOCKPERM\t");
4869       if (log_packets > 1)
4870 	fprintf(stderr, "  state=%d,",
4871 		((struct dockperm_cpacket *) packet)->state );
4872       break;
4873     case CP_UPDATES      :                    /* set number of usecs per *
4874 				               *
4875 					       * * update */
4876       fprintf(stderr, "\nC->S CP_UPDATES\t");
4877       if (log_packets > 1)
4878 	fprintf(stderr, "  usecs=%u,",
4879 		ntohl(((struct updates_cpacket *) packet)->usecs) );
4880       break;
4881     case CP_RESETSTATS   :                    /* reset my stats packet */
4882       fprintf(stderr, "\nC->S CP_RESETSTATS\t");
4883       if (log_packets > 1)
4884 	fprintf(stderr, "  verify=%c,",
4885 		((struct resetstats_cpacket *) packet)->verify );
4886       break;
4887     case CP_RESERVED     :                    /* for future use */
4888       fprintf(stderr, "\nC->S CP_RESERVED\t");
4889       if (log_packets > 1)
4890 	{
4891 	  fprintf(stderr, "  data=" );
4892 	  for( i = 0; i < 16; i++)
4893             fprintf(stderr, "0x%0X ",  (unsigned char)((struct reserved_cpacket *) packet)->data[i]);
4894 	  fprintf(stderr, ", resp=" );
4895 	  for( i = 0; i < 16; i++)
4896             fprintf(stderr, "0x%0X ",  (unsigned char)((struct reserved_cpacket *) packet)->resp[i]);
4897 	  fprintf(stderr, ",");
4898 	}
4899       break;
4900 
4901 #ifdef INCLUDE_SCAN
4902       /* NOTE: not implemented. */
4903     case CP_SCAN         :                    /* ATM: request for player *
4904 					       *
4905 					       * * scan */
4906       fprintf(stderr, "\nC->S CP_SCAN\t");
4907       if (log_packets > 1)
4908 	fprintf(stderr, "  not implemented," );
4909       break;
4910 #endif
4911 
4912     case CP_UDP_REQ      :                    /* request UDP on/off */
4913       fprintf(stderr, "\nC->S CP_UDP_REQ\t");
4914       if (log_packets > 1)
4915 	fprintf(stderr, "  request=%d, connmode=%d, port=%d,",
4916 		((struct udp_req_cpacket *) packet)->request,
4917 		((struct udp_req_cpacket *) packet)->connmode,
4918 		ntohl(((struct udp_req_cpacket *) packet)->port) );
4919       break;
4920     case CP_SEQUENCE     :                    /* sequence # packet */
4921       fprintf(stderr, "\nC->S CP_SEQUENCE\t");
4922       if (log_packets > 1)
4923 	fprintf(stderr, "  sequence=%u,",
4924 		ntohs(((struct sequence_cpacket *) packet)->sequence) );
4925       break;
4926 
4927 #ifdef RSA
4928     case CP_RSA_KEY      :                    /* handles binary * *
4929 					       * verification */
4930       fprintf(stderr, "\nC->S CP_RSA_KEY\t");
4931       if (log_packets > 1)
4932 	{
4933 	fprintf(stderr, "  global=");
4934 	for(i = 0; i < KEY_SIZE; i++)
4935 	  fprintf(stderr, "0x%0X ",((struct rsa_key_cpacket *)packet)->global[i]);
4936 	fprintf(stderr,",");
4937 	fprintf(stderr, "  public=");
4938 	for(i = 0; i < KEY_SIZE; i++)
4939 	  fprintf(stderr, "0x%0X ",((struct rsa_key_cpacket *)packet)->public[i]);
4940 	fprintf(stderr,",");
4941 	fprintf(stderr, "  resp=");
4942 	for(i = 0; i < KEY_SIZE; i++)
4943 	  fprintf(stderr, "0x%0X ",((struct rsa_key_cpacket *)packet)->resp[i]);
4944 	fprintf(stderr,",");
4945 	}
4946       break;
4947 #endif
4948     case CP_PING_RESPONSE :                   /* client response */
4949       /* note: ping.c calls gwrite directly, so we do not see this */
4950       fprintf(stderr, "\nC->S CP_PING_RESPONSE\t");
4951       if (log_packets > 1)
4952 	fprintf(stderr, "  number=%u, pingme=%d, cp_sent=%d, cp_recv=%d",
4953 		((struct ping_cpacket *) packet)->number,
4954 		((struct ping_cpacket *) packet)->pingme,
4955 		ntohl(((struct ping_cpacket *) packet)->cp_sent),
4956 		ntohl(((struct ping_cpacket *) packet)->cp_recv) );
4957       break;
4958 
4959 #ifdef SHORT_PACKETS
4960     case CP_S_REQ        :
4961       fprintf(stderr, "\nC->S CP_S_REQ\t");
4962       if (log_packets > 1)
4963 	fprintf(stderr, "  req=%d, version=%d,",
4964 		((struct shortreq_cpacket *) packet)->req,
4965 		((struct shortreq_cpacket *) packet)->version );
4966       break;
4967     case CP_S_THRS       :
4968       fprintf(stderr, "\nC->S CP_S_THRS\t");
4969       if (log_packets > 1)
4970 	fprintf(stderr, "  thresh=%u,",
4971 		ntohs(((struct threshold_cpacket *) packet)->thresh) );
4972       break;
4973     case CP_S_MESSAGE    :                    /* vari. Message Packet */
4974       fprintf(stderr, "\nC->S CP_S_MESSAGE\t");
4975       if (log_packets > 1)
4976 	fprintf(stderr, "  size=%d, group=%d, indiv=%d, mess=\"%s\",",
4977                 ((struct mesg_cpacket *) packet)->pad1,
4978                 ((struct mesg_cpacket *) packet)->group,
4979                 ((struct mesg_cpacket *) packet)->indiv,
4980                 ((struct mesg_cpacket *) packet)->mesg );
4981       break;
4982     case CP_S_RESERVED   :
4983       fprintf(stderr, "\nC->S CP_S_RESERVED\t");
4984       if (log_packets > 1)
4985 	fprintf(stderr, "  no struct defined,");
4986       break;
4987     case CP_S_DUMMY      :
4988       fprintf(stderr, "\nC->S CP_S_DUMMY\t");
4989       if (log_packets > 1)
4990 	fprintf(stderr, "  no struct defined,");
4991       break;
4992 #endif
4993 
4994 #ifdef FEATURE_PACKETS
4995     case CP_FEATURE      :
4996       fprintf(stderr, "\nC->S CP_FEATURE\t");
4997       if (log_packets > 1)
4998 	fprintf(stderr, "  feature_type=%c, arg1=%d, arg2=%d, value=%d, name=\"%s\",",
4999 		((struct feature_cpacket *) packet)->feature_type,
5000 		((struct feature_cpacket *) packet)->arg1,
5001 		((struct feature_cpacket *) packet)->arg2,
5002 		ntohl(((struct feature_cpacket *) packet)->value),
5003 		((struct feature_cpacket *) packet)->name );
5004       break;
5005 #endif
5006     default             :
5007        fprintf(stderr, "\nC->S UNKNOWN\t");
5008        if(log_packets > 1)
5009 	 fprintf(stderr, "  type=%d,",packet[0]);
5010     }
5011 
5012 
5013 }
5014 
5015 #endif /* PACKET_LOG */
5016 
5017 char   *
strcpyp_return(register char * s1,register char * s2,register int length)5018         strcpyp_return(register char *s1, register char *s2, register int length)
5019 {
5020   while (length && *s2)
5021     {
5022       *s1++ = *s2++;
5023       length--;
5024     }
5025   if (length > 0)
5026     {
5027       while (length--)
5028 	*s1++ = ' ';
5029     }
5030   return s1;
5031 }
5032