Branch oldpackages for 14.07
[14.07/packages.git] / utils / pipacs / src / parser.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include<string.h>
4 #include <time.h>
5 //#include <process.h>
6 #include "parser.h"
7
8 #define printit
9
10 extern BOOL bFilter;
11 extern int iline;
12 extern char * author;
13 extern char myipname[];
14 extern int justheader;
15 extern int gre,sortbysize,fromip,toip;
16 int nomac=1;
17 int mostird=0;
18 char mypbuff[2048];
19 // accounting variables
20 #define MAXHASH 0xffff
21 #define MAXTCPPORT 4096
22 unsigned long *iph=NULL; //[MAXHASH];
23
24 typedef struct {
25                 unsigned short from;
26                 unsigned short to;
27                 unsigned long byte;
28                 unsigned short pkt;
29                 unsigned short sport;
30                 unsigned short dport;
31 } ta;
32
33 ta *acc = NULL;
34 unsigned long tcppb[MAXTCPPORT];
35 unsigned long tcppp[MAXTCPPORT];
36 unsigned long typp[255];
37 unsigned long typb[255];
38 unsigned long udpb,tcpb,udpp,tcpp;
39 time_t elapsed=0;
40 int iCycle=10;
41 int iScreen=1;
42 int iFile=0;
43 long lNum=0;
44 char filename[128];
45 char intlist[128];
46 int iRun=1;
47 int iDetail=0;
48 FILE *f=NULL;
49 int iProto=0;
50 int iSum=0;
51 char execname[255];
52 char pbuf[8196];
53 char str[255];
54 extern char pattern[];
55 #ifndef LINUX
56 int iLnxplus=0;                 // Windows buffer without the MAC frame !
57 #else
58 int iLnxplus=14;                        // Linux plus IP header len =14 !!!
59 #endif
60 //
61 // A list of protocol types in the IP protocol header
62 //
63 char *szProto[255] = {"IP",     //  0
64                    "ICMP",         //  1
65                    "IGMP",         //  2
66                    "GGP",          //  3
67                    "IP",           //  4
68                    "ST",           //  5
69                    "TCP",          //  6
70                    "UCL",          //  7
71                    "EGP",          //  8
72                    "IGP",          //  9
73                    "BBN-RCC-MON",  // 10
74                    "NVP-II",       // 11
75                    "PUP",          // 12
76                    "ARGUS",        // 13
77                    "EMCON",        // 14
78                    "XNET",         // 15
79                    "CHAOS",        // 16
80                    "UDP",          // 17
81                    "MUX",          // 18
82                    "DCN-MEAS",     // 19
83                    "HMP",          // 20
84                    "PRM",          // 21
85                    "XNS-IDP",      // 22
86                    "TRUNK-1",      // 23
87                    "TRUNK-2",      // 24
88                    "LEAF-1",       // 25
89                    "LEAF-2",       // 26
90                    "RDP",          // 27
91                    "IRTP",         // 28
92                    "ISO-TP4",      // 29
93                    "NETBLT",       // 30
94                    "MFE-NSP",      // 31
95                    "MERIT-INP",    // 32
96                    "SEP",          // 33
97                    "3PC",          // 34
98                    "IDPR",         // 35
99                    "XTP",          // 36
100                    "DDP",          // 37
101                    "IDPR-CMTP",    // 38
102                    "TP++",         // 39
103                    "IL",           // 40
104                    "SIP",          // 41
105                    "SDRP",         // 42
106                    "SIP-SR",       // 43
107                    "SIP-FRAG",     // 44
108                    "IDRP",         // 45
109                    "RSVP",         // 46
110                    "GRE",          // 47
111                    "MHRP",         // 48
112                    "BNA",          // 49
113                    "IPSEC-ESP",     // 50
114                    "IPSEC-AH",      // 51
115                    "I-NLSP",       // 52
116                    "SWIPE",        // 53
117                    "NHRP",         // 54
118                    "?55?",   // 55
119                    "?56?",   // 56
120                    "SKIO",   // 57
121                    "V6ICMP",   // 58
122                    "V6NoNXT",   // 59
123                    "V6OPT",   // 60
124                    "int.host",  // 61
125                    "CFTP",         // 62
126                    "loc.net",           // 63
127                    "SAT-EXPAK",    // 64
128                    "KRYPTOLAN",    // 65
129                    "RVD",          // 66
130                    "IPPC",         // 67
131                    "dist.fs", // 68
132                    "SAT-MON",    // 69
133                    "VISA",       // 70
134                    "IPCV",       // 71
135                    "CPNX",       // 72
136                    "CPHB",       // 73
137                    "WSN",        // 74
138                    "PVP",        // 75
139                    "BR-SAT-MON", // 76
140                    "SUN-ND",     // 77
141                    "WB-MON",     // 78
142                    "WB-EXPAK",   // 79
143                    "ISO-IP",     // 80
144                    "VMTP",       // 81
145                    "SECURE-VMTP",// 82
146                    "VINES",      // 83
147                    "TTP",        // 84
148                    "NSFNET-IGP", // 85
149                    "DGP",        // 86
150                    "TCF",        // 87
151                    "IGRP",       // 88
152                    "OSPF",    // 89
153                    "Sprite-RPC", // 90
154                    "LARP",       // 91
155                    "MTP",        // 92
156                    "AX.25",      // 93
157                    "IPIP",       // 94
158                    "MICP",       // 95
159                    "SCC-SP",     // 96
160                    "ETHERIP",    // 97
161                    "ENCAP",      // 98
162                    "priv.enc",    // 99
163                    "GMTP"        // 99
164                   };
165 //
166 // The types of IGMP messages
167 //
168 char *szIgmpType[] = {"",
169                       "Host Membership Query",
170                       "HOst Membership Report",
171                       "",
172                       "",
173                       "",
174                       "Version 2 Membership Report",
175                       "Leave Group",
176                                           "",
177                                           ""
178                      };
179
180 //
181 // Function: PrintRawBytes
182 //
183 // Description:
184 //    This function simply prints out a series of bytes
185 //    as hexadecimal digits.
186 //
187 void PrintRawBytes(BYTE *ptr, DWORD len)
188 {
189     int        i,j;
190 //      if (! iFile) {
191 *(ptr+len)=0;
192 if ((*pattern==0) || strstr(ptr,pattern) ) {
193         fprintf(iFile?f:stdout,"%s",pbuf);
194         fprintf(iFile?f:stdout,"   " );
195                 while (len > 0)    {
196         for(i=0; i < 16; i++)   {
197             fprintf(iFile?f:stdout,"%x%x ", HI_WORD(*ptr), LO_WORD(*ptr));
198             len--;
199             ptr++;
200             if (len == 0) {j=i++; while(++j < 16) fprintf(iFile?f:stdout,"   ");  break; }
201         }
202           fprintf(iFile?f:stdout," ");
203         for(j=0; j < i; j++)    fprintf(iFile?f:stdout,"%c",isprint(*(ptr-i+j))?*(ptr-i+j):'.');
204         if (len) fprintf(iFile?f:stdout,"\n   ");
205     }
206 //      } else {
207 //              fwrite(ptr,sizeof(BYTE),len,f);
208 //      }
209 }
210 }
211
212 static char *ICMPTypeTable[]={
213     "Echo Reply", "ICMP 1", "ICMP 2", "Dest Unreachable","SrcQuench", "Redirect", "6", "7","Echo Request","9","10",
214     "Time Exceed", "ParamPrblm", "Timestamp", "Timestamp reply","InfoRqst", "InfoRply"
215 };
216 static char *Dstunreach[]={
217 "net unreach.","host unreach.","protocol unreach.","port unreach.",
218 "frag needed","source route?","",""
219 };
220 int DecodeICMPHeader(WSABUF *wsabuf, DWORD iphdrlen) {
221     BYTE          *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus );
222     unsigned short type,code,chksum,
223                    id,
224                    seq;
225  unsigned long resptime,r1,r2;
226     BYTE *hhh;
227     SOCKADDR_IN    addr;
228     type=*hdr++; code=*hdr++;
229     sprintf(str," Type:%-12s Code:%3d,",ICMPTypeTable[type],code);
230
231     strcat(pbuf,str);
232     memcpy(&chksum, hdr, 2);
233     hdr += 2; hhh=hdr;
234     memcpy(&id, hdr, 2);
235     hdr += 2;
236     memcpy(&seq, hdr, 2);
237     hdr+=2;
238 //    memcpy(&resptime, hdr, 4);
239 //   hdr+=4;
240     switch (type) {
241     case 3:
242         memcpy(&addr.sin_addr.s_addr, hdr+16, 4);
243         if (code==4 ) sprintf(str,"frag needed-Max MTU:%u at %-15s\n",ntohs(seq), inet_ntoa(addr.sin_addr));
244         else sprintf(str,"%s at %-15s\n",Dstunreach[code&7],inet_ntoa(addr.sin_addr));
245         hdr+=iphdrlen;
246         break;
247     case 11:
248         memcpy(&addr.sin_addr.s_addr, hdr+16, 4);
249         sprintf(str,"%s  at %-15s\n",code?"frag reass. exceed":"ttl exceed",inet_ntoa(addr.sin_addr));
250         hdr+=iphdrlen;
251         break;
252     case 12:
253         memcpy(&addr.sin_addr.s_addr, hdr+16, 4);
254         sprintf(str," err:%d  at %-15s\n",id,inet_ntoa(addr.sin_addr));
255         hdr+=iphdrlen;
256         break;
257     case 4:
258         memcpy(&addr.sin_addr.s_addr, hdr+16, 4);
259         sprintf(str," wait for %-15s\n",ntohs(id),inet_ntoa(addr.sin_addr));
260         hdr+=iphdrlen;
261         break;
262     case 5:
263         memcpy(&addr.sin_addr.s_addr, hhh, 4);
264         sprintf(str," from gw: %-15s\n",inet_ntoa(addr.sin_addr));
265         hdr+=iphdrlen;
266         break;
267     case 0:
268     case 8:
269          sprintf(str," Id:%3u Seq:%3u\n",ntohs(id),ntohs(seq));
270          break;
271     case 13:
272     case 14:
273         memcpy(&resptime, hdr, 4);
274         hdr+=4;
275         memcpy(&r1, hdr, 4);
276         hdr+=4;
277         memcpy(&r2, hdr, 4);
278         hdr+=4;
279         sprintf(str," Id:%3u Seq:%3d Rec/Tr %ld/%ld ms\n",ntohs(id),ntohs(seq),ntohl(r1)-ntohl(resptime),ntohl(r2)-ntohl(resptime));
280         break;
281     case 15:
282     case 16:
283          sprintf(str," Id:%3u Seq:%3d\n",ntohs(id),ntohs(seq));
284          break;
285     }
286     strcat(pbuf,str);
287     return hdr-(BYTE *)(wsabuf->buf + iphdrlen + iLnxplus);
288 }
289
290 //
291 // Function: DecodeIGMPHeader
292 //
293 // Description:
294 //    This function takes a pointer to a buffer containing
295 //    an IGMP packet and prints it out in a readable form.
296 //
297
298 int DecodeIGMPHeader(WSABUF *wsabuf, DWORD iphdrlen) {
299     BYTE          *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus);
300     unsigned short chksum,
301                    version,
302                    type,
303                    maxresptime;
304     SOCKADDR_IN    addr;
305     version = HI_WORD(*hdr);
306     type    = LO_WORD(*hdr);
307
308     hdr++;
309     maxresptime = *hdr;
310     hdr++;
311
312     memcpy(&chksum, hdr, 2);
313     chksum = ntohs(chksum);
314     hdr += 2;
315
316     memcpy(&(addr.sin_addr.s_addr), hdr, 4);
317     sprintf(str,"   IGMP HEADER:\n");
318     strcat(pbuf,str);
319     if ((type == 1) || (type == 2))        version = 1;
320     else        version = 2;
321     sprintf(str,"   IGMP Version = %d\n   IGMP Type = %s\n",version, szIgmpType[type]);
322     strcat(pbuf,str);
323     if (version == 2) {
324      sprintf(str,"   Max Resp Time = %d\n", maxresptime);
325      strcat(pbuf,str);
326     }
327     sprintf(str,"   IGMP Grp Addr = %s\n", inet_ntoa(addr.sin_addr));
328     strcat(pbuf,str);
329
330     return 8;
331 }
332
333 //
334 // Function: DecodeUDPHeader
335 //
336 // Description:
337 //    This function takes a buffer which points to a UDP
338 //    header and prints it out in a readable form.
339 //
340 int DecodeUDPHeader(WSABUF *wsabuf, DWORD iphdrlen) {
341     BYTE          *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus);
342     unsigned short shortval,
343                    udp_src_port,
344                    udp_dest_port,
345                    udp_len,
346                    udp_chksum;
347     memcpy(&shortval, hdr, 2);
348     udp_src_port = ntohs(shortval);
349     hdr += 2;
350
351     memcpy(&shortval, hdr, 2);
352     udp_dest_port = ntohs(shortval);
353     hdr += 2;
354
355     memcpy(&shortval, hdr, 2);
356     udp_len = ntohs(shortval);
357     hdr += 2;
358
359     memcpy(&shortval, hdr, 2);
360     udp_chksum = ntohs(shortval);
361     hdr += 2;
362
363     sprintf(str," UDP:  SPort: %-05d  | DPort: %-05d",udp_src_port, udp_dest_port);
364     strcat(pbuf,str);
365     sprintf(str," | Len: %-05d | CSum: 0x%08x\n",udp_len, udp_chksum);
366     strcat(pbuf,str);
367     return hdr-(BYTE *)(wsabuf->buf + iphdrlen + iLnxplus);
368 }
369
370 //
371 // Function: DecodeTCPHeader
372 //
373 // Description:
374 //    This function takes a buffer pointing to a TCP header
375 //    and prints it out in a readable form.
376 //
377 int DecodeTCPHeader(WSABUF *wsabuf, DWORD iphdrlen) {
378     BYTE           *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus);
379     unsigned short shortval;
380     unsigned long   longval;
381
382     memcpy(&shortval, hdr, 2);
383     shortval = ntohs(shortval);
384     sprintf(str," TCP: SPort: %u", shortval);
385     strcat(pbuf,str);
386     hdr += 2;
387
388     memcpy(&shortval, hdr, 2);
389     shortval = ntohs(shortval);
390     sprintf(str,"  DPort: %u", shortval);
391     strcat(pbuf,str);
392     hdr += 2;
393
394     memcpy(&longval, hdr, 4);
395     longval = ntohl(longval);
396     sprintf(str," Seq: %lX", longval);
397     strcat(pbuf,str);
398     hdr += 4;
399
400     memcpy(&longval, hdr, 4);
401     longval = ntohl(longval);
402     sprintf(str," ACK: %lX", longval);
403     strcat(pbuf,str);
404     hdr += 4;
405 //    printf("   Header Len : %d (bytes %d)\n", HI_WORD(*hdr), (HI_WORD(*hdr) * 4));
406
407     memcpy(&shortval, hdr, 2);
408     shortval = ntohs(shortval) & 0x3F;
409     sprintf(str," Flags: ");
410     strcat(pbuf,str);
411     if (shortval & 0x20)        strcat(pbuf,"URG ");
412     if (shortval & 0x10)        strcat(pbuf,"ACK ");
413     if (shortval & 0x08)        strcat(pbuf,"PSH ");
414     if (shortval & 0x04)        strcat(pbuf,"RST ");
415     if (shortval & 0x02)        strcat(pbuf,"SYN ");
416     if (shortval & 0x01)        strcat(pbuf,"FIN ");
417     strcat(pbuf,"\n");
418     hdr += 2;
419
420     memcpy(&shortval, hdr, 2);
421     shortval = ntohs(shortval);
422 //    printf("   Window size: %d\n", shortval);
423     hdr += 2;
424
425     memcpy(&shortval, hdr, 2);
426     shortval = ntohs(shortval);
427 //    printf("   TCP Chksum : %d\n", shortval);
428     hdr += 2;
429
430     memcpy(&shortval, hdr, 2);
431     shortval = ntohs(shortval);
432     hdr += 2;
433 //    printf("   Urgent ptr : %d\n", shortval);
434
435     return hdr-(BYTE *)(wsabuf->buf + iphdrlen + iLnxplus);
436 }
437
438 int DecodeGREHeader(WSABUF *wsabuf, DWORD iphdrlen,DWORD bytesret,
439  unsigned int srcip, unsigned short srcport, unsigned long srcnet,unsigned int destip, unsigned short destport, unsigned long destnet,
440  unsigned short xport,unsigned int xip, unsigned long xnet)
441  {
442     BYTE           *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus);
443     unsigned short shortval;
444     unsigned long   longval;
445     int ipe;
446     BYTE           *orihdr;
447     char *sstr;
448     SOCKADDR_IN         srcaddr;
449
450     orihdr=hdr;
451     memcpy(&shortval, hdr, 2);
452     shortval = ntohs(shortval);
453     sprintf(str," GRE Flag: %u Prot:", shortval);
454     strcat(mypbuff,str);
455     hdr += 2;
456
457     memcpy(&shortval, hdr, 2);
458     shortval = ntohs(shortval);
459     ipe=0;
460     sstr=str;
461 //    sprintf(str,"  Prot: %u", shortval);
462     switch ( shortval ) {
463     case 4: sstr="SNA";
464        break;
465     case 0xfe: sstr="OSI";
466        break;
467     case 0x200: sstr="PUP";
468        break;
469     case 0x600: sstr="XNS";
470        break;
471     case 0x800: sstr="IP";
472         ipe=1;
473        break;
474     case 0x804: sstr="Chaos";
475        break;
476     case 0x806: sstr="ARP";
477        break;
478     case 0x6558: sstr="Tr.bridge";
479        break;
480     default: sprintf(str,"%u", shortval);
481        break;
482     }
483     hdr += 2;
484     strcat(mypbuff,sstr);
485     if (ipe && gre) {
486         int plusment,jj,protoment;
487         plusment=iLnxplus;
488         protoment=iProto;
489         if (iProto==47)  iProto=0;
490         iLnxplus+=4;
491         nomac=0;
492         iLnxplus=plusment+24;
493         DecodeIPHeader(wsabuf,srcip,srcport,srcnet,destip,destport,destnet,bytesret,xport,xip,xnet);
494         nomac=1;
495         iLnxplus=plusment;
496         iProto=protoment;
497     }
498 return -1;
499 //    return hdr-(BYTE *)(wsabuf->buf + iphdrlen + iLnxplus);
500 }
501
502
503 int ClearIPAcc() {
504         unsigned long i;
505         ta *tai;
506         for(i=0;i<MAXHASH;i++) *(iph + i)=0;
507         tai=acc;
508         for(i=0;i<MAXHASH;i++) { tai->from=tai->to=0; tai++; }
509         for (i=0;i<MAXTCPPORT; i++) tcppb[i]=tcppp[i]=0;
510         udpb=udpp=tcpp=tcpb=0;
511         for (i=0;i<255; i++) typp[i]=0;
512         for (i=0;i<255; i++) typb[i]=0;
513         return 0;
514         };
515
516 int InitIPAcc() {
517         acc=malloc(MAXHASH*sizeof(ta));
518         iph=malloc(MAXHASH*sizeof(long));
519         if (!acc || !iph ) return 0;
520         ClearIPAcc();
521         time(&elapsed);
522         return 1;
523 }
524
525 int bytesort(const void *s1, const void *s2) { // sorting tale in byte order
526         ta *d1;
527         ta *d2;
528         d1= (ta *)s1; d2=(ta *)s2;
529         if (d1->byte > d2->byte) return -1;
530         if (d1->byte < d2->byte) return 1;
531         return 0;
532 }
533 int countsort(const void *s1, const void *s2) { // sorting tale in packet count order
534         ta *d1;
535         ta *d2;
536         d1= (ta *)s1; d2=(ta *)s2;
537         if (d1->pkt > d2->pkt) return -1;
538         if (d1->pkt < d2->pkt) return 1;
539         return 0;
540 }
541 int CloseIPAcc( long ti) {
542         unsigned long i;
543         ta *tai;
544     SOCKADDR_IN    srcaddr;
545     SOCKADDR_IN    dstaddr;
546         float ff;
547         char str[16];
548         unsigned long j,k,l;
549         int lin=0;
550         int linn;
551
552         time(&elapsed);
553         if (iFile) f=fopen(filename,"w+");
554         k=0;
555         if (sortbysize) qsort(acc,MAXHASH,sizeof(ta),bytesort);
556         else  qsort(acc,MAXHASH,sizeof(ta),countsort);
557         ff=0.0;
558         for (i=0;i<255;i++) ff+=typb[i];
559         for (i=0; i<MAXHASH; i++) {
560             tai=acc + i;
561             if ((tai->from!=0) && (tai->to!=0)) ++k;
562         }
563         if (iScreen) {
564 #ifndef LINUX
565                 system("cls");
566 #else
567                 system("clear");
568 //              printf("\033[1~");
569 #endif
570                 printf("%-16s Speed: %5.2f Kbit/s , %ld IP pairs / %ld secs.    %s@%s.hu",myipname,ff/ti/1024*8,k,ti,author,author);
571                 printf("\nProt:"); j=0; ++lin;
572                 while (1) {
573                         l=k=0;
574                         for (i=0;i<100;i++) if ( typb[i]>k) { k=typb[i]; l=i; }
575                         if (k==0) break;
576                         if ((j>0) && ((j%3)==0)) { printf("\n     "); ++lin; }
577                         if (k>1024*1024) printf(" %-8.8s:%5.1fk/%-6.1f M",szProto[l],(float)typp[l]/1024,(float)k/(1024*1024));
578                         else if (k>1024) printf(" %-8.8s:%5ld/%-6.1f k",szProto[l],typp[l],(float)k/1024);
579                         else printf(" %-8.8s:%5ld/%-8ld",szProto[l],typp[l],k);
580                         typb[l]=0;
581                         ++j;
582                 }
583                 printf("\nPort:"); j=0; ++lin;
584                 k=0; linn=lin;
585                 while (1) {
586                         l=k=0;
587                         for (i=0;i<MAXTCPPORT;i++) if (tcppb[i]>k) { k=tcppb[i]; l=i; }
588                         if (k==0) break;
589                         if (j && (j%4)==0) {
590                                 if (lin >= linn+1) break;
591                                 printf("\n     ");
592                                 ++lin;
593                         }
594                         if (k>1024*1024) printf(" %04d:%4.1fk/%-5.1f M",l,(float)tcppp[l]/1024,(float)k/(1024*1024));
595                         else if (k>1024) printf(" %04d:%4ld/%-5.1f k",l,tcppp[l],(float)k/1024);
596                         else printf(" %04d:%4ld/%-7ld",l,tcppp[l],k);
597                         tcppb[l]=0;
598                         ++j;
599                 }
600         } else if (f) {
601                 fprintf(f,"%-16s Speed: %5.2f Kbit/s , %ld IP pairs / %ld secs.    %s@%s.hu",myipname,ff/ti/1024*8,k,ti,author,author);
602                 fprintf(f,"\nProt:"); j=0;
603                 while (1) {
604                         l=k=0;
605                         for (i=0;i<100;i++) if ( typb[i]>k) { k=typb[i]; l=i; }
606                         if (k==0) break;
607                         if (k>1024*1024) fprintf(f," %-8.8s:%5.1fk/%-6.1f M",szProto[l],(float)typp[l]/1024,(float)k/(1024*1024));
608                         else if (k>1024) fprintf(f," %-8.8s:%5ld/%-6.1f k",szProto[l],typp[l],(float)k/1024);
609                         else fprintf(f," %-8.8s:%5ld/%-8ld",szProto[l],typp[l],k);
610                         typb[l]=0;
611                         ++j;
612                 }
613                 printf("\nPort:"); j=0;
614                 k=0; linn=lin;
615                 while (1) {
616                         l=k=0;
617                         for (i=0;i<MAXTCPPORT;i++) if (tcppb[i]>k) { k=tcppb[i]; l=i; }
618                         if (k==0) break;
619                         if (k>1024*1024) fprintf(f," %04d:%4.1fk/%-5.1f M",l,(float)tcppp[l]/1024,(float)k/(1024*1024));
620                         else if (k>1024) fprintf(f," %04d:%4ld/%-5.1f k",l,tcppp[l],(float)k/1024);
621                         else fprintf(f," %04d:%4ld/%-7ld",l,tcppp[l],k);
622                         tcppb[l]=0;
623                         ++j;
624                 }
625         }
626
627         for (i=0; i<MAXHASH; i++) {
628                 tai=acc + i;
629                 if ((tai->from!=0) && (tai->to!=0)) { ++k;
630                 if (!iSum) {
631                         dstaddr.sin_addr.s_addr = htonl(*(iph+tai->from));
632                         srcaddr.sin_addr.s_addr = htonl(*(iph+(tai->to)));
633                         strcpy(str,inet_ntoa(dstaddr.sin_addr));
634                         if (iScreen && (++lin<iline) ) printf("\n%-15s\t%-15s\t%5d pkt, %10ld byte :%7.2f Kbps",str,inet_ntoa(srcaddr.sin_addr),tai->pkt,tai->byte,((float)tai->byte)/ti/1024*8);
635                         if (f) fprintf(f,"%-15s\t%-15s\t%d\t%ld\n",str,inet_ntoa(srcaddr.sin_addr),tai->pkt,tai->byte);
636                 }
637                 }
638         }
639       if (iScreen) printf("\n");
640 #ifdef LINUX
641         if (iScreen) fflush(stdout);
642 #endif
643         ClearIPAcc();
644         if (f) {
645                 char cmdline[255];
646                 fclose(f);
647 //              if (*execname) _spawnle(_P_NOWAIT,execname,execname,filename);
648 //              if (*execname) _execl(execname,execname);
649                 if (*execname) {
650 #ifndef LINUX
651                 sprintf(cmdline,"%s %s",execname,filename);
652 #else
653                 sprintf(cmdline,"%s %s",execname,filename);
654 #endif
655                 system(cmdline);
656 //              iRun=0;
657                 }
658         }
659         f=NULL;
660         return 0;
661 }
662
663 unsigned short FindIPHash( unsigned long ip ) {
664         unsigned short hashval;
665         unsigned long *ipt;
666
667         hashval = (unsigned short)(((ip&0xFFFF0000)>>16) ^ (ip&0x0000FFFF));
668         ipt=iph + hashval;
669         while (*ipt != 0 && (*ipt!=ip)) { ipt++; hashval++; }
670         if (*ipt==0) *ipt=ip;
671         return hashval;
672 }
673
674 unsigned short SetIPAcc( unsigned long src, unsigned long dst, unsigned long byte, unsigned short typ, unsigned short sport, unsigned short dport) {
675         unsigned short from,to,hash;
676         ta *tai;
677         hash=0;
678         if (src) {
679
680                 if (fromip) from=FindIPHash(src); else from=-1;
681                 if (toip) to=FindIPHash(dst); else to=-1;
682                 hash=from^to;
683                 tai=acc + hash;
684                 while ( ((tai->from!=from) && (tai->to!=to)) && ((tai->from!=0) && (tai->to!=0)) ) {tai++; hash++; }
685                 if ((tai->from==0)&&(tai->to==0)) {
686                         tai->byte=byte; tai->from=from; tai->to=to; tai->pkt=1;
687                 } else { tai->byte+=byte; tai->pkt++; }
688
689                 typp[typ]++;
690                 typb[typ]+=byte;
691                 if ((sport>0) && (sport<MAXTCPPORT)) { tcppp[sport]++; tcppb[sport]+=byte; }
692                 if ((dport>0) && (dport<MAXTCPPORT)) { tcppp[dport]++; tcppb[dport]+=byte; }
693         }
694         return hash;
695 }
696
697 //
698 // Function: DecodeIPHeader
699 //
700 // Description:
701 //    This function takes a pointer to an IP header and prints
702 //    it out in a readable form.
703 //
704 int DecodeIPHeader(WSABUF *wsabuf, unsigned int srcip, unsigned short srcport, unsigned long srcnet,
705         unsigned int destip, unsigned short destport, unsigned long destnet, DWORD bytesret,
706         unsigned short xport,unsigned int xip, unsigned long xnet)
707 {
708     BYTE                        *hdr = (BYTE *)wsabuf->buf,
709                                         *nexthdr = NULL,
710                                         *ohdr;
711     unsigned short      shortval;
712     SOCKADDR_IN         srcaddr,
713                                         destaddr;
714
715     unsigned short ip_version,
716                    ip_hdr_len,
717                    ip_tos,
718                    ip_total_len,
719                    ip_id,
720                    ip_flags,
721                    ip_ttl,
722                    ip_frag_offset,
723                    ip_proto,
724                    ip_hdr_chksum,
725                    ip_src_port,
726                    ip_dest_port;
727     unsigned int   ip_src,
728                    ip_dest;
729     BOOL           bPrint = FALSE;
730     char       ip_prtype=0;
731     int     j;
732     time_t tt;
733     struct tm *tmm;
734
735     ohdr=hdr;
736     if (iLnxplus) ip_prtype=*(hdr+iLnxplus-1);
737     if (ip_prtype) return 0;
738     hdr += iLnxplus;
739     ip_version = HI_WORD(*hdr);
740     ip_hdr_len = LO_WORD(*hdr) * 4;
741     nexthdr = (BYTE *)((BYTE *)hdr + ip_hdr_len);
742     hdr++;
743
744     ip_tos = *hdr;
745     hdr++;
746
747     memcpy(&shortval, hdr, 2);
748     ip_total_len = ntohs(shortval);
749     hdr += 2;
750
751     memcpy(&shortval, hdr, 2);
752     ip_id = ntohs(shortval);
753     hdr += 2;
754
755     ip_flags = ((*hdr) >> 5);
756
757     memcpy(&shortval, hdr, 2);
758     ip_frag_offset = ((ntohs(shortval)) & 0x1FFF);
759     hdr += 2;
760
761     ip_ttl = *hdr;
762     hdr++;
763
764     ip_proto = *hdr;
765     hdr++;
766
767     memcpy(&shortval, hdr, 2);
768     ip_hdr_chksum = ntohs(shortval);
769     hdr += 2;
770
771     memcpy(&srcaddr.sin_addr.s_addr, hdr, 4);
772     ip_src = ntohl(srcaddr.sin_addr.s_addr);
773     hdr += 4;
774
775     memcpy(&destaddr.sin_addr.s_addr, hdr, 4);
776     ip_dest = ntohl(destaddr.sin_addr.s_addr);
777     hdr += 4;
778     //
779     // If packet is UDP, TCP, or IGMP read ahead and
780     //  get the port values.
781     //
782         ip_src_port=ip_dest_port=0;
783     if (((ip_proto == 2) ||
784          (ip_proto == 6) ||
785          (ip_proto == 17)) ) //&& bFilter)
786     {
787         memcpy(&ip_src_port, nexthdr, 2);
788         ip_src_port = ntohs(ip_src_port);
789         memcpy(&ip_dest_port, nexthdr+2, 2);
790         ip_dest_port = ntohs(ip_dest_port);
791
792     };
793     bPrint = 0;
794 //      xaok=   (xip!=0) && (((xip&xnet)==(ip_src&xnet))||((xip&xnet)==(ip_dest&xnet)));
795 //      saok= ((srcip==0)||((srcip&srcnet)==(ip_src&srcnet)));
796 //      daok = ((destip==0)||((destip&destnet)==(ip_dest&destnet)));
797 //      xpok=(xport!=0) && ((xport==ip_src_port)||(xport==ip_dest_port));
798 //      spok=((srcport==0)||(srcport == ip_src_port));
799 //      dpok=((destport==0)||(destport == ip_dest_port));
800 //printf("\nf:%d xa:%d sa:%d da:%d xp:%d sp:%d dp:%d",bFilter,xaok,saok,daok,xpok,spok,dpok);
801 //      if (!bFilter || ( (xaok||(saok&&daok)) && (xpok||(spok&&dpok)))) {
802 if ((!bFilter) || ((ip_proto==47)&&gre) ||
803                 (
804                 ((iProto==0)||(ip_proto==iProto)) &&
805                  (
806                   ((xip!=0) && (((xip&xnet)==(ip_src&xnet))||((xip&xnet)==(ip_dest&xnet)))
807                   ) || (
808                    ((srcip==0) || ((srcip&srcnet)==(ip_src&srcnet))) && ((destip==0)||((destip&destnet)==(ip_dest&destnet)))
809                   )
810                  )
811                  &&
812                  (
813                   ((xport!=0) && ((xport==ip_src_port)||(xport==ip_dest_port))
814                   ) || (
815                    ((srcport==0)||(srcport == ip_src_port))&&((destport==0)||(destport == ip_dest_port))
816                   )
817                  )
818                 )
819                 ) {
820                         if (! iDetail) {
821                             if ((ip_proto==47)&&gre) {
822                             *mypbuff=0;
823                              DecodeGREHeader(wsabuf, ip_hdr_len, bytesret,
824                     srcip,srcport,srcnet,destip,destport,destnet,xport,xip,xnet);
825 //                            SetIPAcc(0,0,0,0,0,0);
826                             return ip_hdr_len;
827                             }
828                             SetIPAcc(ip_src,ip_dest,ip_total_len,ip_proto,ip_src_port,ip_dest_port);
829                         }
830                         else bPrint=TRUE;
831 //                        printf("%d %ld %ld %ld %ld",ip_proto,xip,xip&xnet,ip_src&xnet,ip_dest&xnet);
832         } else {
833                         if (! iDetail)          SetIPAcc(0,0,0,0,0,0);
834 //                      else bPrint=TRUE;
835         }
836         time(&tt);
837         if ((!iSum && ( tt-elapsed > iCycle)) || !iRun || mostird) {
838             mostird=0;
839                 if (! iDetail) CloseIPAcc(tt-elapsed-1);
840                 else {
841                         time(&elapsed);
842                         if (f) fclose(f);
843                         if (iFile) f=fopen(filename,"a");
844                 }
845         }
846         if (lNum) { if (--lNum <= 0) iRun=0; }
847
848     //
849     *pbuf=0;
850     if (bPrint)    {
851                 tmm=localtime(&tt);
852 if (! nomac ) {
853     strcpy(pbuf,mypbuff);
854 } else {
855         sprintf(str,"\n%4.4d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d ",
856             tmm->tm_year+1900,tmm->tm_mon+1,tmm->tm_mday,tmm->tm_hour,tmm->tm_min,tmm->tm_sec);
857         strcat(pbuf,str);
858 #ifdef LINUX
859         sprintf(str,"%x:%x:%x:%x:%x:%x > %x:%x:%x:%x:%x:%x",*ohdr,*(ohdr+1),*(ohdr+2),*(ohdr+3),*(ohdr+4),*(ohdr+5),
860             *(ohdr+6),*(ohdr+7),*(ohdr+8),*(ohdr+9),*(ohdr+10),*(ohdr+11));
861         strcat(pbuf,str);
862 #endif
863 }
864         sprintf(str,"  %d bytes\n%-15s>", ip_total_len, inet_ntoa(srcaddr.sin_addr));
865         strcat(pbuf,str);
866         sprintf(str,"%-15s", inet_ntoa(destaddr.sin_addr));
867         strcat(pbuf,str);
868         sprintf(str," TTL:%-3d Proto:%-6s F:%d/%d TOS:%X%X\n",
869             ip_ttl, szProto[ip_proto],ip_flags,ip_frag_offset,HI_WORD(ip_tos), LO_WORD(ip_tos));
870         strcat(pbuf,str);
871         if (iFile) strcat(pbuf,".");
872         strcpy(mypbuff,pbuf);
873
874     }
875     else        return ip_hdr_len;
876
877     if (justheader) { if (*pbuf) fprintf(iFile?f:stdout,"%s",pbuf); return ip_hdr_len; }
878         if (iDetail) {
879                 switch (ip_proto)    {
880                         case 1:        // ICMP
881                                 j=DecodeICMPHeader(wsabuf, ip_hdr_len);
882                                 break;
883                         case 2:        // IGMP
884                                 j=DecodeIGMPHeader(wsabuf, ip_hdr_len);
885                                 break;
886                         case 6:        // TCP
887                                 j=DecodeTCPHeader(wsabuf, ip_hdr_len);
888                                 break;
889                         case 17:       // UDP
890                                 j=DecodeUDPHeader(wsabuf, ip_hdr_len);
891                                 break;
892                         case 47:       // UDP
893                                 j=DecodeGREHeader(wsabuf, ip_hdr_len, bytesret,
894                     srcip,srcport,srcnet,destip,destport,destnet,xport,xip,xnet);
895                                 break;
896                         default:
897                                 j=0;  hdr=(BYTE *)wsabuf->buf;
898                                 sprintf(str,"   No decoder installed for protocol\n");
899                                 strcat(pbuf,str);
900                                 break;
901                 }
902                 if (j>=0) PrintRawBytes(hdr+j,bytesret-j-ip_hdr_len-12); //(hdr-(BYTE *)(wsabuf->buf + iLnxplus)));
903         }
904         else if (*pbuf) fprintf(iFile?f:stdout,"%s",pbuf);
905
906     return ip_hdr_len;
907 }