add pipacs package (thanks to Janos)
[openwrt/svn-archive/archive.git] / openwrt / package / 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 }