13 extern char myipname[];
14 extern int justheader;
15 extern int gre,sortbysize,fromip,toip;
19 // accounting variables
20 #define MAXHASH 0xffff
21 #define MAXTCPPORT 4096
22 unsigned long *iph=NULL; //[MAXHASH];
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;
54 extern char pattern[];
56 int iLnxplus=0; // Windows buffer without the MAC frame !
58 int iLnxplus=14; // Linux plus IP header len =14 !!!
61 // A list of protocol types in the IP protocol header
63 char *szProto[255] = {"IP", // 0
166 // The types of IGMP messages
168 char *szIgmpType[] = {"",
169 "Host Membership Query",
170 "HOst Membership Report",
174 "Version 2 Membership Report",
181 // Function: PrintRawBytes
184 // This function simply prints out a series of bytes
185 // as hexadecimal digits.
187 void PrintRawBytes(BYTE *ptr, DWORD len)
192 if ((*pattern==0) || strstr(ptr,pattern) ) {
193 fprintf(iFile?f:stdout,"%s",pbuf);
194 fprintf(iFile?f:stdout," " );
196 for(i=0; i < 16; i++) {
197 fprintf(iFile?f:stdout,"%x%x ", HI_WORD(*ptr), LO_WORD(*ptr));
200 if (len == 0) {j=i++; while(++j < 16) fprintf(iFile?f:stdout," "); break; }
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 ");
207 // fwrite(ptr,sizeof(BYTE),len,f);
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"
216 static char *Dstunreach[]={
217 "net unreach.","host unreach.","protocol unreach.","port unreach.",
218 "frag needed","source route?","",""
220 int DecodeICMPHeader(WSABUF *wsabuf, DWORD iphdrlen) {
221 BYTE *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus );
222 unsigned short type,code,chksum,
225 unsigned long resptime,r1,r2;
228 type=*hdr++; code=*hdr++;
229 sprintf(str," Type:%-12s Code:%3d,",ICMPTypeTable[type],code);
232 memcpy(&chksum, hdr, 2);
236 memcpy(&seq, hdr, 2);
238 // memcpy(&resptime, hdr, 4);
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));
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));
253 memcpy(&addr.sin_addr.s_addr, hdr+16, 4);
254 sprintf(str," err:%d at %-15s\n",id,inet_ntoa(addr.sin_addr));
258 memcpy(&addr.sin_addr.s_addr, hdr+16, 4);
259 sprintf(str," wait for %-15s\n",ntohs(id),inet_ntoa(addr.sin_addr));
263 memcpy(&addr.sin_addr.s_addr, hhh, 4);
264 sprintf(str," from gw: %-15s\n",inet_ntoa(addr.sin_addr));
269 sprintf(str," Id:%3u Seq:%3u\n",ntohs(id),ntohs(seq));
273 memcpy(&resptime, 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));
283 sprintf(str," Id:%3u Seq:%3d\n",ntohs(id),ntohs(seq));
287 return hdr-(BYTE *)(wsabuf->buf + iphdrlen + iLnxplus);
291 // Function: DecodeIGMPHeader
294 // This function takes a pointer to a buffer containing
295 // an IGMP packet and prints it out in a readable form.
298 int DecodeIGMPHeader(WSABUF *wsabuf, DWORD iphdrlen) {
299 BYTE *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus);
300 unsigned short chksum,
305 version = HI_WORD(*hdr);
306 type = LO_WORD(*hdr);
312 memcpy(&chksum, hdr, 2);
313 chksum = ntohs(chksum);
316 memcpy(&(addr.sin_addr.s_addr), hdr, 4);
317 sprintf(str," IGMP HEADER:\n");
319 if ((type == 1) || (type == 2)) version = 1;
321 sprintf(str," IGMP Version = %d\n IGMP Type = %s\n",version, szIgmpType[type]);
324 sprintf(str," Max Resp Time = %d\n", maxresptime);
327 sprintf(str," IGMP Grp Addr = %s\n", inet_ntoa(addr.sin_addr));
334 // Function: DecodeUDPHeader
337 // This function takes a buffer which points to a UDP
338 // header and prints it out in a readable form.
340 int DecodeUDPHeader(WSABUF *wsabuf, DWORD iphdrlen) {
341 BYTE *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus);
342 unsigned short shortval,
347 memcpy(&shortval, hdr, 2);
348 udp_src_port = ntohs(shortval);
351 memcpy(&shortval, hdr, 2);
352 udp_dest_port = ntohs(shortval);
355 memcpy(&shortval, hdr, 2);
356 udp_len = ntohs(shortval);
359 memcpy(&shortval, hdr, 2);
360 udp_chksum = ntohs(shortval);
363 sprintf(str," UDP: SPort: %-05d | DPort: %-05d",udp_src_port, udp_dest_port);
365 sprintf(str," | Len: %-05d | CSum: 0x%08x\n",udp_len, udp_chksum);
367 return hdr-(BYTE *)(wsabuf->buf + iphdrlen + iLnxplus);
371 // Function: DecodeTCPHeader
374 // This function takes a buffer pointing to a TCP header
375 // and prints it out in a readable form.
377 int DecodeTCPHeader(WSABUF *wsabuf, DWORD iphdrlen) {
378 BYTE *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus);
379 unsigned short shortval;
380 unsigned long longval;
382 memcpy(&shortval, hdr, 2);
383 shortval = ntohs(shortval);
384 sprintf(str," TCP: SPort: %u", shortval);
388 memcpy(&shortval, hdr, 2);
389 shortval = ntohs(shortval);
390 sprintf(str," DPort: %u", shortval);
394 memcpy(&longval, hdr, 4);
395 longval = ntohl(longval);
396 sprintf(str," Seq: %lX", longval);
400 memcpy(&longval, hdr, 4);
401 longval = ntohl(longval);
402 sprintf(str," ACK: %lX", longval);
405 // printf(" Header Len : %d (bytes %d)\n", HI_WORD(*hdr), (HI_WORD(*hdr) * 4));
407 memcpy(&shortval, hdr, 2);
408 shortval = ntohs(shortval) & 0x3F;
409 sprintf(str," Flags: ");
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 ");
420 memcpy(&shortval, hdr, 2);
421 shortval = ntohs(shortval);
422 // printf(" Window size: %d\n", shortval);
425 memcpy(&shortval, hdr, 2);
426 shortval = ntohs(shortval);
427 // printf(" TCP Chksum : %d\n", shortval);
430 memcpy(&shortval, hdr, 2);
431 shortval = ntohs(shortval);
433 // printf(" Urgent ptr : %d\n", shortval);
435 return hdr-(BYTE *)(wsabuf->buf + iphdrlen + iLnxplus);
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)
442 BYTE *hdr = (BYTE *)((BYTE *)wsabuf->buf + iphdrlen + iLnxplus);
443 unsigned short shortval;
444 unsigned long longval;
451 memcpy(&shortval, hdr, 2);
452 shortval = ntohs(shortval);
453 sprintf(str," GRE Flag: %u Prot:", shortval);
457 memcpy(&shortval, hdr, 2);
458 shortval = ntohs(shortval);
461 // sprintf(str," Prot: %u", shortval);
462 switch ( shortval ) {
465 case 0xfe: sstr="OSI";
467 case 0x200: sstr="PUP";
469 case 0x600: sstr="XNS";
471 case 0x800: sstr="IP";
474 case 0x804: sstr="Chaos";
476 case 0x806: sstr="ARP";
478 case 0x6558: sstr="Tr.bridge";
480 default: sprintf(str,"%u", shortval);
484 strcat(mypbuff,sstr);
486 int plusment,jj,protoment;
489 if (iProto==47) iProto=0;
492 iLnxplus=plusment+24;
493 DecodeIPHeader(wsabuf,srcip,srcport,srcnet,destip,destport,destnet,bytesret,xport,xip,xnet);
499 // return hdr-(BYTE *)(wsabuf->buf + iphdrlen + iLnxplus);
506 for(i=0;i<MAXHASH;i++) *(iph + i)=0;
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;
517 acc=malloc(MAXHASH*sizeof(ta));
518 iph=malloc(MAXHASH*sizeof(long));
519 if (!acc || !iph ) return 0;
525 int bytesort(const void *s1, const void *s2) { // sorting tale in byte order
528 d1= (ta *)s1; d2=(ta *)s2;
529 if (d1->byte > d2->byte) return -1;
530 if (d1->byte < d2->byte) return 1;
533 int countsort(const void *s1, const void *s2) { // sorting tale in packet count order
536 d1= (ta *)s1; d2=(ta *)s2;
537 if (d1->pkt > d2->pkt) return -1;
538 if (d1->pkt < d2->pkt) return 1;
541 int CloseIPAcc( long ti) {
553 if (iFile) f=fopen(filename,"w+");
555 if (sortbysize) qsort(acc,MAXHASH,sizeof(ta),bytesort);
556 else qsort(acc,MAXHASH,sizeof(ta),countsort);
558 for (i=0;i<255;i++) ff+=typb[i];
559 for (i=0; i<MAXHASH; i++) {
561 if ((tai->from!=0) && (tai->to!=0)) ++k;
568 // printf("\033[1~");
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;
574 for (i=0;i<100;i++) if ( typb[i]>k) { k=typb[i]; l=i; }
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);
583 printf("\nPort:"); j=0; ++lin;
587 for (i=0;i<MAXTCPPORT;i++) if (tcppb[i]>k) { k=tcppb[i]; l=i; }
590 if (lin >= linn+1) break;
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);
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;
605 for (i=0;i<100;i++) if ( typb[i]>k) { k=typb[i]; l=i; }
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);
613 printf("\nPort:"); j=0;
617 for (i=0;i<MAXTCPPORT;i++) if (tcppb[i]>k) { k=tcppb[i]; l=i; }
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);
627 for (i=0; i<MAXHASH; i++) {
629 if ((tai->from!=0) && (tai->to!=0)) { ++k;
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);
639 if (iScreen) printf("\n");
641 if (iScreen) fflush(stdout);
647 // if (*execname) _spawnle(_P_NOWAIT,execname,execname,filename);
648 // if (*execname) _execl(execname,execname);
651 sprintf(cmdline,"%s %s",execname,filename);
653 sprintf(cmdline,"%s %s",execname,filename);
663 unsigned short FindIPHash( unsigned long ip ) {
664 unsigned short hashval;
667 hashval = (unsigned short)(((ip&0xFFFF0000)>>16) ^ (ip&0x0000FFFF));
669 while (*ipt != 0 && (*ipt!=ip)) { ipt++; hashval++; }
670 if (*ipt==0) *ipt=ip;
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;
680 if (fromip) from=FindIPHash(src); else from=-1;
681 if (toip) to=FindIPHash(dst); else to=-1;
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++; }
691 if ((sport>0) && (sport<MAXTCPPORT)) { tcppp[sport]++; tcppb[sport]+=byte; }
692 if ((dport>0) && (dport<MAXTCPPORT)) { tcppp[dport]++; tcppb[dport]+=byte; }
698 // Function: DecodeIPHeader
701 // This function takes a pointer to an IP header and prints
702 // it out in a readable form.
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)
708 BYTE *hdr = (BYTE *)wsabuf->buf,
711 unsigned short shortval;
715 unsigned short ip_version,
736 if (iLnxplus) ip_prtype=*(hdr+iLnxplus-1);
737 if (ip_prtype) return 0;
739 ip_version = HI_WORD(*hdr);
740 ip_hdr_len = LO_WORD(*hdr) * 4;
741 nexthdr = (BYTE *)((BYTE *)hdr + ip_hdr_len);
747 memcpy(&shortval, hdr, 2);
748 ip_total_len = ntohs(shortval);
751 memcpy(&shortval, hdr, 2);
752 ip_id = ntohs(shortval);
755 ip_flags = ((*hdr) >> 5);
757 memcpy(&shortval, hdr, 2);
758 ip_frag_offset = ((ntohs(shortval)) & 0x1FFF);
767 memcpy(&shortval, hdr, 2);
768 ip_hdr_chksum = ntohs(shortval);
771 memcpy(&srcaddr.sin_addr.s_addr, hdr, 4);
772 ip_src = ntohl(srcaddr.sin_addr.s_addr);
775 memcpy(&destaddr.sin_addr.s_addr, hdr, 4);
776 ip_dest = ntohl(destaddr.sin_addr.s_addr);
779 // If packet is UDP, TCP, or IGMP read ahead and
780 // get the port values.
782 ip_src_port=ip_dest_port=0;
783 if (((ip_proto == 2) ||
785 (ip_proto == 17)) ) //&& bFilter)
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);
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) ||
804 ((iProto==0)||(ip_proto==iProto)) &&
806 ((xip!=0) && (((xip&xnet)==(ip_src&xnet))||((xip&xnet)==(ip_dest&xnet)))
808 ((srcip==0) || ((srcip&srcnet)==(ip_src&srcnet))) && ((destip==0)||((destip&destnet)==(ip_dest&destnet)))
813 ((xport!=0) && ((xport==ip_src_port)||(xport==ip_dest_port))
815 ((srcport==0)||(srcport == ip_src_port))&&((destport==0)||(destport == ip_dest_port))
821 if ((ip_proto==47)&&gre) {
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);
828 SetIPAcc(ip_src,ip_dest,ip_total_len,ip_proto,ip_src_port,ip_dest_port);
831 // printf("%d %ld %ld %ld %ld",ip_proto,xip,xip&xnet,ip_src&xnet,ip_dest&xnet);
833 if (! iDetail) SetIPAcc(0,0,0,0,0,0);
837 if ((!iSum && ( tt-elapsed > iCycle)) || !iRun || mostird) {
839 if (! iDetail) CloseIPAcc(tt-elapsed-1);
843 if (iFile) f=fopen(filename,"a");
846 if (lNum) { if (--lNum <= 0) iRun=0; }
853 strcpy(pbuf,mypbuff);
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);
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));
864 sprintf(str," %d bytes\n%-15s>", ip_total_len, inet_ntoa(srcaddr.sin_addr));
866 sprintf(str,"%-15s", inet_ntoa(destaddr.sin_addr));
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));
871 if (iFile) strcat(pbuf,".");
872 strcpy(mypbuff,pbuf);
875 else return ip_hdr_len;
877 if (justheader) { if (*pbuf) fprintf(iFile?f:stdout,"%s",pbuf); return ip_hdr_len; }
881 j=DecodeICMPHeader(wsabuf, ip_hdr_len);
884 j=DecodeIGMPHeader(wsabuf, ip_hdr_len);
887 j=DecodeTCPHeader(wsabuf, ip_hdr_len);
890 j=DecodeUDPHeader(wsabuf, ip_hdr_len);
893 j=DecodeGREHeader(wsabuf, ip_hdr_len, bytesret,
894 srcip,srcport,srcnet,destip,destport,destnet,xport,xip,xnet);
897 j=0; hdr=(BYTE *)wsabuf->buf;
898 sprintf(str," No decoder installed for protocol\n");
902 if (j>=0) PrintRawBytes(hdr+j,bytesret-j-ip_hdr_len-12); //(hdr-(BYTE *)(wsabuf->buf + iLnxplus)));
904 else if (*pbuf) fprintf(iFile?f:stdout,"%s",pbuf);