root/cafu/trunk/CaTools/ReadDump.cpp

Revision 455, 24.0 KB (checked in by Carsten, 4 months ago)

Updated copyright banners (in C++ files).

Line 
1/*
2=================================================================================
3This file is part of Cafu, the open-source game engine and graphics engine
4for multiplayer, cross-platform, real-time 3D action.
5Copyright (C) 2002-2012 Carsten Fuchs Software.
6
7Cafu is free software: you can redistribute it and/or modify it under the terms
8of the GNU General Public License as published by the Free Software Foundation,
9either version 3 of the License, or (at your option) any later version.
10
11Cafu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13PURPOSE. See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with Cafu. If not, see <http://www.gnu.org/licenses/>.
17
18For support and more information about Cafu, visit us at <http://www.cafu.de>.
19=================================================================================
20*/
21
22#ifdef _WIN32
23#include <winsock2.h>
24#else
25#include <netinet/in.h>
26#endif
27
28#include <stdio.h>
29#include <stdlib.h>
30
31#include "../Ca3DE/NetConst.hpp"
32
33
34FILE* InFile=NULL;
35
36char ReadByte()
37{
38    char Data1=0xFF;
39
40    if (fread(&Data1, 1, 1, InFile)==0) { }
41    return Data1;
42}
43
44
45unsigned short ReadWord(bool n2h=true)
46{
47    unsigned short Data2=0xFFFF;
48
49    if (fread(&Data2, 2, 1, InFile)==0) { }
50    return n2h ? ntohs(Data2) : Data2;
51}
52
53
54unsigned long ReadLong(bool n2h=true)
55{
56    unsigned long Data4=0xFFFFFFFF;
57
58    if (fread(&Data4, 4, 1, InFile)==0) { }
59    return n2h ? ntohl(Data4) : Data4;
60}
61
62
63float ReadFloat()
64{
65    unsigned long l=ReadLong();
66
67    return *(float*)&l;
68}
69
70
71void CloseInFile()
72{
73    if (InFile) fclose(InFile);
74    InFile=NULL;
75}
76
77
78int main(int ArgC, const char* ArgV[])
79{
80    printf("ReadDump: Reads network dumps in libpcap format and\n");
81    printf("          decodes them with Cafu network protocol\n");
82    printf("\n");
83
84    if (ArgC!=2)
85    {
86        printf("USAGE: ReadDump <Path/FileName>\n");
87        return 1;
88    }
89
90
91    InFile=fopen(ArgV[1], "rb");
92
93    if (InFile==NULL)
94    {
95        printf("ERROR: Unable to open '%s'\n", ArgV[1]);
96        return 1;
97    }
98
99    atexit(CloseInFile);
100
101
102    // Header
103    unsigned long MagicNumber=ReadLong(false);
104    printf("Magic number             0x%lX\n", MagicNumber);
105    printf("Version                  %u.%u\n", ReadWord(false), ReadWord(false));
106    printf("TimeZone                 %li\n", ReadLong(false));
107    printf("Accuracy of TimeStamps   %lu\n", ReadLong(false));
108    printf("Max length of packets    %lu\n", ReadLong(false));
109
110    unsigned long DataLink=ReadLong(false);
111    printf("Data link type           %lu\n", DataLink);
112    printf("\n");
113
114    if (MagicNumber!=0xA1B2C3D4)
115    {
116        printf("ERROR: Bad magic number 0x%lX, expected 0xA1B2C3D4\n", MagicNumber);
117        return 1;
118    }
119
120    if (DataLink!=1)
121    {
122        printf("ERROR: Bad data link type %lu, expected 1 (Ethernet 10Mb)\n", DataLink);
123        return 1;
124    }
125
126    while (!feof(InFile))
127    {
128        // 1. Skip any remaining data from the last packet!
129        static unsigned long BytesRemaining=0;
130
131        while (BytesRemaining)
132        {
133            ReadByte();
134            BytesRemaining--;
135        }
136
137
138        // 2. Normal processing of next packet
139        static unsigned long PacketNumber   =1;
140        static double        TimeStampOffset=0;
141
142        unsigned long TimeStampSeconds    =ReadLong(false);
143        unsigned long TimeStampMicroSec   =ReadLong(false);
144        unsigned long PacketLengthCaptured=ReadLong(false);      // Number of bytes saved in file
145        unsigned long PacketLength        =ReadLong(false);      // Number of bytes of actual packet
146
147        BytesRemaining=PacketLengthCaptured;
148
149        if (PacketNumber==1) TimeStampOffset=double(TimeStampSeconds)+double(TimeStampMicroSec)/1000000.0;
150        printf("%5lu", PacketNumber);
151        // printf("%5u", PacketLength);
152        printf("%11.6f", double(TimeStampSeconds)+double(TimeStampMicroSec)/1000000.0-TimeStampOffset);
153        PacketNumber++;
154
155        if (PacketLength!=PacketLengthCaptured)
156        {
157            printf("\nBAD: PacketLength!=PacketLengthCaptured (%lu!=%lu)\n", PacketLength, PacketLengthCaptured);
158            printf("     *** Make sure that packets are not saved truncated after capturing! ***\n");
159            continue;
160        }
161
162/*      if (BytesRemaining<xxxx)
163        {
164            printf("\nBAD: packet too short! Expected at least xxx, found only xxx\n");
165            continue;
166        }*/
167
168        // char EthernetDest  [6];
169        // char EthernetSource[6];
170        char c;
171
172        for (c=0; c<6; c++) { /*EthernetDest  [c]=*/ReadByte(); BytesRemaining--; }
173        for (c=0; c<6; c++) { /*EthernetSource[c]=*/ReadByte(); BytesRemaining--; }
174        // printf(" %02X:%02X:%02X:%02X:%02X:%02X", EthernetSource[0], EthernetSource[1], EthernetSource[2], EthernetSource[3], EthernetSource[4], EthernetSource[5]);
175        // printf(" %02X:%02X:%02X:%02X:%02X:%02X", EthernetDest  [0], EthernetDest  [1], EthernetDest  [2], EthernetDest  [3], EthernetDest  [4], EthernetDest  [5]);
176
177        unsigned short EthernetNextProtocol=ReadWord(); BytesRemaining-=2;
178
179        if (EthernetNextProtocol!=0x0800)
180        {
181            printf("\nBAD: Network layer protocol is not IP, expected 0x0800, found 0x%04X\n", EthernetNextProtocol);
182            continue;
183        }
184
185        char IPVerOpts=ReadByte(); BytesRemaining--;
186
187        if (IPVerOpts!=0x45)
188        {
189            printf("\nBAD: IP version or options field, expected 0x45, got 0x%02X\n", IPVerOpts);
190            continue;
191        }
192
193        char TypeOfService=ReadByte(); BytesRemaining--;
194
195        if (TypeOfService)
196        {
197            printf("\nBAD: Unknown type of service 0x%02X\n", TypeOfService);
198            continue;
199        }
200
201        unsigned short IPTotalLength=ReadWord(); BytesRemaining-=2;
202        printf("%5u", IPTotalLength);
203
204        ReadByte(); BytesRemaining--;   // 16-bit Identification
205        ReadByte(); BytesRemaining--;
206        ReadByte(); BytesRemaining--;   // Flags
207        ReadByte(); BytesRemaining--;   // Fragmentation offset
208
209        char TimeToLive=ReadByte(); BytesRemaining--;
210        printf(" TTL%4u", TimeToLive);
211
212        char TransportLayerProtocol=ReadByte(); BytesRemaining--;
213
214        if (TransportLayerProtocol!=17)
215        {
216            printf("\nBAD: Transport layer protocol is not UDP, expected 17, got %u\n", TransportLayerProtocol);
217            continue;
218        }
219
220        unsigned short IPHeaderChecksum=ReadWord(); BytesRemaining-=2;
221        printf(" IP Checksum %u\n", IPHeaderChecksum);
222
223        // char IPSource[4];
224        // char IPDest  [4];
225
226        for (c=0; c<4; c++) { /*IPSource[c]=*/ReadByte(); BytesRemaining--; }
227        for (c=0; c<4; c++) { /*IPDest  [c]=*/ReadByte(); BytesRemaining--; }
228        // printf(" %3u.%3u.%3u.%3u", IPSource[0], IPSource[1], IPSource[2], IPSource[3]);
229        // printf(" %3u.%3u.%3u.%3u", IPDest  [0], IPDest  [1], IPDest  [2], IPDest  [3]);
230
231        unsigned short SourcePort =ReadWord(); BytesRemaining-=2;
232        unsigned short DestPort   =ReadWord(); BytesRemaining-=2;
233        unsigned short UDPLength  =ReadWord(); BytesRemaining-=2;
234        unsigned short UDPChecksum=ReadWord(); BytesRemaining-=2;
235
236        unsigned short DataLength=UDPLength-8;  // UDP Header is 8 Bytes large
237        printf("UDP Checksum %u  DataLen %4u", UDPChecksum, DataLength);
238
239        if (SourcePort!=30000 && DestPort!=30000)
240        {
241            printf("\nBAD: Neither source port nor destination port is Cafu default server port 30000\n");
242            continue;
243        }
244
245        unsigned long SequNr1=ReadLong(); BytesRemaining-=4;
246        unsigned long SequNr2=ReadLong(); BytesRemaining-=4;
247
248        if (SourcePort==30000)
249        {
250            printf(" Sv->Cl");
251
252            if (SequNr1==0xFFFFFFFF) printf(" CONNLESS");
253                                else printf(" %08lX", SequNr1);
254            printf(" %08lX", SequNr2);
255
256            if (SequNr1==0xFFFFFFFF)
257            {
258                // decode connection-less packets from server to client
259                switch (ReadByte())
260                {
261                    case SC0_ACK:  printf(" ACK "); break;
262                    case SC0_NACK: printf(" NACK");
263                                   while (true)
264                                   {
265                                       char c=ReadByte();
266
267                                       BytesRemaining--;
268                                       DataLength--;
269                                       if (!c) break;
270                                       printf("%c", c);
271                                   }
272                                   break;
273                    default:       printf(" UNKN");
274                }
275                BytesRemaining--;
276                DataLength--;
277            }
278            else
279            {
280                // decode connected packets from server to client
281                while (true)
282                {
283                    // printf(" BytesRemaining %u   DataLength %u\n", BytesRemaining, DataLength);
284                    if (BytesRemaining==0 || DataLength<=8) { printf("###\n"); break; }
285
286                    char NextCommand=ReadByte(); BytesRemaining--; DataLength--;
287
288                    printf(" | ");
289
290                    switch (NextCommand)
291                    {
292                        case SC1_WorldInfo:
293                        {
294                            printf("WorldInfo ");
295
296                            // GameName
297                            while (true)
298                            {
299                                char c=ReadByte();
300
301                                BytesRemaining--;
302                                DataLength--;
303                                if (!c) break;
304                                printf("%c", c);
305                            }
306                            printf(" ");
307
308                            // WorldName
309                            while (true)
310                            {
311                                char c=ReadByte();
312
313                                BytesRemaining--;
314                                DataLength--;
315                                if (!c) break;
316                                printf("%c", c);
317                            }
318                            printf(" ");
319
320                            printf("OurEntID %3lu", ReadLong());
321                            BytesRemaining-=4;
322                            DataLength-=4;
323                            break;
324                        }
325
326                        case SC1_EntityBaseLine:
327                        {
328                            printf("EntBaseLine ");
329
330                            unsigned long EntityID =ReadLong(); BytesRemaining-=4; DataLength-=4;
331                            unsigned long TypeID   =ReadByte(); BytesRemaining-=1; DataLength-=1;
332                            unsigned long MapFileID=ReadLong(); BytesRemaining-=4; DataLength-=4;
333
334                            printf("EntID %3lu, Type%3lu, MapFileID %3lu", EntityID, TypeID, MapFileID);
335
336                            unsigned long  FieldMaskBaseLine1=ReadLong(); BytesRemaining-=4; DataLength-=4;
337                            unsigned short FieldMaskBaseLine2=0; if (FieldMaskBaseLine1 & 0x02000000) { FieldMaskBaseLine2=ReadWord(); BytesRemaining-=2; DataLength-=2; }
338                            unsigned long  FieldMaskBaseLine3=0; if (FieldMaskBaseLine1 & 0x04000000) { FieldMaskBaseLine3=ReadLong(); BytesRemaining-=4; DataLength-=4; }
339
340                            if (FieldMaskBaseLine1 & 0x00000001) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
341                            if (FieldMaskBaseLine1 & 0x00000002) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
342                            if (FieldMaskBaseLine1 & 0x00000004) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
343                            if (FieldMaskBaseLine1 & 0x00000008) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
344                            if (FieldMaskBaseLine1 & 0x00000010) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
345                            if (FieldMaskBaseLine1 & 0x00000020) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
346                            if (FieldMaskBaseLine1 & 0x00000040) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
347                            if (FieldMaskBaseLine1 & 0x00000080) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
348                            if (FieldMaskBaseLine1 & 0x00000100) { ReadWord (); BytesRemaining-=2; DataLength-=2; }
349                            if (FieldMaskBaseLine1 & 0x00000200) { ReadWord (); BytesRemaining-=2; DataLength-=2; }
350                            if (FieldMaskBaseLine1 & 0x00000400) { ReadWord (); BytesRemaining-=2; DataLength-=2; }
351                            if (FieldMaskBaseLine1 & 0x00000800) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
352                            if (FieldMaskBaseLine1 & 0x00001000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
353                            if (FieldMaskBaseLine1 & 0x00002000) { printf(" "); while (true) { char c=ReadByte(); BytesRemaining--; DataLength--; printf("%c", c); if (!c) break; } }
354                            if (FieldMaskBaseLine1 & 0x00004000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
355                            if (FieldMaskBaseLine1 & 0x00008000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
356                            if (FieldMaskBaseLine1 & 0x00010000) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
357                            if (FieldMaskBaseLine1 & 0x00020000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
358                            if (FieldMaskBaseLine1 & 0x00040000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
359                            if (FieldMaskBaseLine1 & 0x00080000) { ReadLong (); BytesRemaining-=4; DataLength-=4; }
360                            if (FieldMaskBaseLine1 & 0x00100000) { ReadLong (); BytesRemaining-=4; DataLength-=4; }
361                            if (FieldMaskBaseLine1 & 0x00200000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
362                            if (FieldMaskBaseLine1 & 0x00400000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
363                            if (FieldMaskBaseLine1 & 0x00800000) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
364                            if (FieldMaskBaseLine1 & 0x01000000) { ReadLong (); BytesRemaining-=4; DataLength-=4; }
365
366                            char Nr;
367
368                            for (Nr=0; Nr<16; Nr++) if (FieldMaskBaseLine2 & (1L << Nr)) { ReadWord (); BytesRemaining-=2; DataLength-=2; }
369                            for (Nr=0; Nr<32; Nr++) if (FieldMaskBaseLine3 & (1L << Nr)) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
370                            break;
371                        }
372
373                        case SC1_FrameInfo:
374                            printf("FrameInfo%6lu", ReadLong());
375                            printf("%6lu", ReadLong());
376                            BytesRemaining-=8;
377                            DataLength-=8;
378                            break;
379
380                        case SC1_EntityUpdate:
381                        {
382                            printf("SC1_EntityUpdate ");
383
384                            unsigned long EntID     =ReadLong(); BytesRemaining-=4; DataLength-=4; printf("NewEntID  %6lu", EntID     );
385                            unsigned long FieldMask1=ReadLong(); BytesRemaining-=4; DataLength-=4; // printf("FieldMask %6u", FieldMask1);
386
387                            unsigned short FieldMask2=0; if (FieldMask1 & 0x02000000) { FieldMask2=ReadWord(); BytesRemaining-=2; DataLength-=2; }
388                            unsigned long  FieldMask3=0; if (FieldMask1 & 0x04000000) { FieldMask3=ReadLong(); BytesRemaining-=4; DataLength-=4; }
389
390                            if (FieldMask1 & 0x00000001) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
391                            if (FieldMask1 & 0x00000002) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
392                            if (FieldMask1 & 0x00000004) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
393                            if (FieldMask1 & 0x00000008) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
394                            if (FieldMask1 & 0x00000010) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
395                            if (FieldMask1 & 0x00000020) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
396                            if (FieldMask1 & 0x00000040) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
397                            if (FieldMask1 & 0x00000080) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
398                            if (FieldMask1 & 0x00000100) { ReadWord (); BytesRemaining-=2; DataLength-=2; }
399                            if (FieldMask1 & 0x00000200) { ReadWord (); BytesRemaining-=2; DataLength-=2; }
400                            if (FieldMask1 & 0x00000400) { ReadWord (); BytesRemaining-=2; DataLength-=2; }
401                            if (FieldMask1 & 0x00000800) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
402                            if (FieldMask1 & 0x00001000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
403                            if (FieldMask1 & 0x00002000) { printf(" "); while (true) { char c=ReadByte(); BytesRemaining--; DataLength--; printf("%c", c); if (!c) break; } }
404                            if (FieldMask1 & 0x00004000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
405                            if (FieldMask1 & 0x00008000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
406                            if (FieldMask1 & 0x00010000) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
407                            if (FieldMask1 & 0x00020000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
408                            if (FieldMask1 & 0x00040000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
409                            if (FieldMask1 & 0x00080000) { ReadLong (); BytesRemaining-=4; DataLength-=4; }
410                            if (FieldMask1 & 0x00100000) { ReadLong (); BytesRemaining-=4; DataLength-=4; }
411                            if (FieldMask1 & 0x00200000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
412                            if (FieldMask1 & 0x00400000) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
413                            if (FieldMask1 & 0x00800000) { ReadFloat(); BytesRemaining-=4; DataLength-=4; }
414                            if (FieldMask1 & 0x01000000) { ReadLong (); BytesRemaining-=4; DataLength-=4; }
415
416                            char Nr;
417
418                            for (Nr=0; Nr<16; Nr++) if (FieldMask2 & (1L << Nr)) { ReadWord (); BytesRemaining-=2; DataLength-=2; }
419                            for (Nr=0; Nr<32; Nr++) if (FieldMask3 & (1L << Nr)) { ReadByte (); BytesRemaining-=1; DataLength-=1; }
420                            break;
421                        }
422
423                        case SC1_DropClient:
424                            printf("SC1_DropClient %3lu Reason: ", ReadLong()); BytesRemaining-=4; DataLength-=4;
425
426                            // Reason.
427                            while (true)
428                            {
429                                char c=ReadByte();
430
431                                BytesRemaining--;
432                                DataLength--;
433                                if (!c) break;
434                                printf("%c", c);
435                            }
436                            printf(" ");
437                            break;
438
439                        case SC1_ChatMsg:
440                            printf("ChatMsg ");
441                            while (true)
442                            {
443                                char c=ReadByte();
444
445                                BytesRemaining--;
446                                DataLength--;
447                                if (!c) break;
448                                printf("%c", c);
449                            }
450                            break;
451
452                        default:
453                            printf("UNKNOWN 0x%X", NextCommand);
454                    }
455                }
456            }
457        }
458        else  // DestPort==30000
459        {
460            printf(" Cl->Sv");
461
462            if (SequNr1==0xFFFFFFFF) printf(" CONNLESS");
463                                else printf(" %08lX", SequNr1);
464            printf(" %08lX", SequNr2);
465
466            if (SequNr1==0xFFFFFFFF)
467            {
468                // decode connection-less packets from client to server
469                switch (ReadByte())
470                {
471                    case CS0_NoOperation: printf(" NOP "); break;
472                    case CS0_Ping:        printf(" PING"); break;
473                    case CS0_Connect:     printf(" CONN"); break;
474                    case CS0_Info:        printf(" INFO"); break;
475                    default:              printf(" UNKN");
476                }
477                BytesRemaining--;
478                DataLength--;
479            }
480            else
481            {
482                // decode connected packets from client to server
483                /*  char ClientID=ReadByte(); // OBSOLETE
484
485                BytesRemaining--;
486                DataLength--;
487
488                printf(" ClID%2u", ClientID); */
489
490                while (true)
491                {
492                    char NextCommand=ReadByte();
493
494                    BytesRemaining--;
495                    DataLength--;
496
497                    if (DataLength==0) break;
498                    if (NextCommand==0xFF)
499                    {
500                        printf(" ###");
501                        break;
502                    }
503
504                    printf(" | ");
505
506                    switch (NextCommand)
507                    {
508                        /* case CS1_PlayerCmd:  // VERALTET! PRÜFEN!
509                        {
510                            printf("PlayerCmd Keys 0x%08X", ReadLong());
511                            printf(" Hdg %5u", ReadWord());
512
513                            unsigned long FrameTime=ReadLong());
514                            printf(  " FrameTime%5.2f", *(float*)&FrameTime);
515                            BytesRemaining-=10;
516                            DataLength-=10;
517                            break;
518                        } */
519
520                        case CS1_Disconnect:
521                            printf("Disconnect");
522                            break;
523
524                        case CS1_SayToAll:
525                            printf("SayToAll ");
526                            while (true)
527                            {
528                                char c=ReadByte();
529
530                                BytesRemaining--;
531                                DataLength--;
532                                if (!c) break;
533                                printf("%c", c);
534                            }
535                            break;
536
537                        case CS1_WorldInfoACK:
538                            printf("WorldInfoACK ");
539                            while (true)
540                            {
541                                char c=ReadByte();
542
543                                BytesRemaining--;
544                                DataLength--;
545                                if (!c) break;
546                                printf("%c", c);
547                            }
548                            break;
549
550                        /* case CS1_FrameInfo: // VERALTET! PRÜFEN!
551                            printf("FrameInfo%6u", ReadLong());
552                            BytesRemaining-=4;
553                            DataLength-=4;
554                            break; */
555
556                        default:
557                            printf("UNKNOWN 0x%X", NextCommand);
558                    }
559                }
560            }
561        }
562
563        printf("\n");
564    }
565
566    return 0;
567}
Note: See TracBrowser for help on using the browser.