home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 68 / IOPROG_68.ISO / soft / Codice / SPS.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2003-03-04  |  11.7 KB  |  394 lines

  1. //SPS.cpp
  2. //Simple Packet Sniffer (SPS)
  3. //(c) Elia Florio (eflorio@edmaster.it)
  4. #include <stdio.h>
  5.  
  6. //WINSOCK 2 - RAW SOCKET SUPPORT
  7. #include <winsock2.h>
  8. #pragma comment (lib, "ws2_32.lib")
  9. #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)    //required by winsock2.h
  10. #define MAX_PACKET_SIZE (65536-20)            //2^16 - ip_header_length
  11.  
  12. //log file C:\SPSLOG.TXT
  13. FILE *file=NULL;
  14. char* filename;
  15.  
  16. //menu' variables
  17. bool filelog;
  18. bool hexlog;
  19. char ipaddr[255];
  20. int  filter_type;
  21.  
  22. //-----------------------------------------------------------------
  23. // INTERNET HEADERS
  24. //-----------------------------------------------------------------
  25.  
  26. //IPv4 HEADER (20 BYTES)
  27. typedef struct iphdr
  28. {
  29.     unsigned char  VerIHL;            // 8-bit - Version (4-bit) + IP Header Length (4-bit)
  30.     unsigned char  Tos;                // 8-bit - Type of Service
  31.     unsigned short Total_len;        //16-bit - Total Length
  32.     unsigned short ID;                //16-bit - Identification
  33.     unsigned short Flags_and_Frags; //16-bit - Flags (3-bit) + Fragment offset (13-bit)
  34.     unsigned char  TTL;                // 8-bit - Time To Live 
  35.     unsigned char  Protocol;        // 8-bit - Protocol
  36.     unsigned short Checksum;        //16-bit - Header Checksum
  37.     unsigned long  SrcIP;            //32-bit - Source IP Address
  38.     unsigned long  DstIP;            //32-bit - Destination IP Address
  39.     //unsigned long Opt_and_Padd;
  40. } IpHeader;
  41.  
  42.  
  43. //TCP HEADER (20 BYTES + DATA)
  44. typedef struct tcphd
  45. {
  46.     unsigned short SrcPort;            //16-bit - Source Port
  47.     unsigned short DstPort;            //16-bit - Destination Port
  48.     unsigned long  SeqNumber;        //32-bit - Seq Number
  49.     unsigned long  AckNumber;        //32-bit - Ack Number
  50.     unsigned short Off_Res_Ctrl;    //16-bit - D-Offset (4-bit) + Reserved (6-bit) + Ctrl (6-bit)
  51.     unsigned short Window;            //16-bit - Window
  52.     unsigned short Checksum;        //16-bit - Checksum
  53.     unsigned short Urgent;            //16-bit - Urgent Pointer
  54.     //unsigned long Opt_and_Padd;
  55.     unsigned char dati[MAX_PACKET_SIZE];
  56. } TcpHeader;
  57.  
  58.  
  59. //UDP HEADER (8 BYTES + DATA)
  60. typedef struct udphd
  61. {
  62.     unsigned short SrcPort;            //16-bit - Source Port
  63.     unsigned short DstPort;            //16-bit - Destination Port
  64.     unsigned short Length;            //16-bit - Datagram Length
  65.     unsigned short Checksum;        //16-bit - Checksum
  66.     unsigned char dati[MAX_PACKET_SIZE];
  67. } UdpHeader;
  68.  
  69.  
  70. // ICMP Header (8 BYTES)
  71. typedef struct icmphd
  72.     unsigned char  icmp_type;         //  8-bit - Type of message
  73.     unsigned char  icmp_code;        //  8-bit - Code
  74.     unsigned short icmp_cksum;       // 16-bit - Checksum
  75.     unsigned short icmp_id;          // 16-bit - Identifer
  76.     unsigned short icmp_seq;         // 16-bit - Sequence number
  77. } IcmpHeader;
  78. //-----------------------------------------------------------------
  79.  
  80.  
  81. //PACKET FILTERING/ANALYSING FUNCTION
  82. void PacketFilter(char* Buffer, int Size)
  83. {
  84.     IpHeader *iphdr;
  85.     TcpHeader *tcphd;
  86.     UdpHeader *udphd;
  87.     IcmpHeader *icmphd;
  88.     struct sockaddr_in SockAddr;
  89.     unsigned short iphdrlen;
  90.     char C;
  91.  
  92.     //Analyze packet
  93.     iphdr = (IpHeader *)Buffer;
  94.     iphdrlen = (iphdr->VerIHL << 4);
  95.     memcpy(&C, &iphdrlen, 1);
  96.     iphdrlen = (C >> 4) * 4; //20 bytes
  97.  
  98.     //Analyze IP Header
  99.     printf("\n=====CAPTURED PACKET======\n");
  100.     if (filelog) fprintf(file,"\n=====CAPTURED PACKET======\n");
  101.     
  102.     printf("* [Header IP] \n");
  103.     if (filelog) fprintf(file,"* [Header IP] \n");
  104.     
  105.     memset(&SockAddr, 0, sizeof(SockAddr));
  106.     SockAddr.sin_addr.s_addr = iphdr->SrcIP;
  107.     printf("  From: %s ", inet_ntoa(SockAddr.sin_addr));
  108.     if (filelog) fprintf(file,"  From: %s ", inet_ntoa(SockAddr.sin_addr));
  109.  
  110.     memset(&SockAddr, 0, sizeof(SockAddr));
  111.     SockAddr.sin_addr.s_addr = iphdr->DstIP;
  112.     printf("  To: %s \n", inet_ntoa(SockAddr.sin_addr));
  113.     if (filelog) fprintf(file,"  To: %s \n", inet_ntoa(SockAddr.sin_addr));
  114.  
  115.     printf("  ID: %i \n", ntohs(iphdr->ID));
  116.     if (filelog) fprintf(file,"  ID: %i \n", ntohs(iphdr->ID));
  117.  
  118.     printf("  TTL: %i \n", ntohs(iphdr->TTL));
  119.     if (filelog) fprintf(file,"  TTL: %i \n", ntohs(iphdr->TTL));
  120.  
  121.     printf("  Total Length: %i \n\n", ntohs(iphdr->Total_len));
  122.     if (filelog) fprintf(file,"  Total Length: %i \n\n", ntohs(iphdr->Total_len));
  123.  
  124.  
  125.     //Analyze IP Protocol
  126.     switch (iphdr->Protocol)
  127.     {
  128.     case 1:
  129.         printf("* [Protocol: ICMP] \n");
  130.         if (filelog) fprintf(file,"* [Protocol: ICMP] \n");
  131.  
  132.         if(filter_type==4 || filter_type==3) {
  133.         if (Size > iphdrlen)
  134.         {
  135.             //Analyze ICMP
  136.             icmphd = (IcmpHeader *)(Buffer + iphdrlen);
  137.  
  138.             printf("  Type: %i  ", icmphd->icmp_type);
  139.             if (filelog) fprintf(file,"  Type: %i  ", icmphd->icmp_type);
  140.  
  141.             printf("  Code: %i  \n", icmphd->icmp_code);
  142.             if (filelog) fprintf(file,"  Code: %i  \n", icmphd->icmp_code);
  143.  
  144.             printf("  IcmpSeq: %i \n", icmphd->icmp_seq);
  145.             if (filelog) fprintf(file,"  IcmpSeq: %i \n", icmphd->icmp_seq);
  146.  
  147.             if(icmphd->icmp_type==0)  {printf("  (EchoReply)"); if(filelog) fprintf(file,"  (EchoReply)");}
  148.             if(icmphd->icmp_type==3)  {printf("  (DestUnreach)"); if(filelog) fprintf(file,"  (DestUnreach)");}
  149.             if(icmphd->icmp_type==8)  {printf("  (EchoRequest)"); if(filelog) fprintf(file,"  (EchoRequest)");}
  150.             if(icmphd->icmp_type==11) {printf("  (TimeExceed)"); if(filelog) fprintf(file,"  (TimeExceed)");}
  151.             if(icmphd->icmp_type==30) {printf("  (TraceRoute)"); if(filelog) fprintf(file,"  (TraceRoute)");}
  152.             }
  153.         }
  154.  
  155.         break;
  156.  
  157.  
  158.     case 6:
  159.         printf("* [Protocol: TCP] \n");
  160.         if (filelog) fprintf(file,"* [Protocol: TCP] \n");
  161.  
  162.         if(filter_type==4 || filter_type==1) {
  163.         if (Size > iphdrlen)
  164.         {
  165.             //Analyze TCP
  166.             tcphd = (TcpHeader *)(Buffer + iphdrlen);
  167.             
  168.             printf("  Data Offset = %i\n",ntohs(tcphd->Off_Res_Ctrl)>>12);
  169.             if(filelog) fprintf(file,"  Data Offset = %i\n",ntohs(tcphd->Off_Res_Ctrl)>>12);            
  170.  
  171.             printf("  SrcPort: %i  =>  ", ntohs(tcphd->SrcPort));
  172.             if (filelog) fprintf(file,"  SrcPort: %i  =>  ", ntohs(tcphd->SrcPort));
  173.             
  174.             //try to guess upper-layer protocol looking src port number
  175.             if(ntohs(tcphd->SrcPort)==25)   {printf("(SMTP)"); if(filelog) fprintf(file,"(SMTP)");}
  176.             if(ntohs(tcphd->SrcPort)==80)   {printf("(HTTP)"); if(filelog) fprintf(file,"(HTTP)");}
  177.             if(ntohs(tcphd->SrcPort)==110)  {printf("(POP3)"); if(filelog) fprintf(file,"(POP3)");}
  178.             if(ntohs(tcphd->SrcPort)==6667) {printf("(IRC)");  if(filelog) fprintf(file,"(IRC)");}
  179.  
  180.             printf("\n  DstPort: %i \n", ntohs(tcphd->DstPort));
  181.             if(filelog) fprintf(file,"\n  DstPort: %i \n", ntohs(tcphd->DstPort));
  182.  
  183.             printf("  SeqNumber: %i \n  AckNumber: %i \n", ntohl(tcphd->SeqNumber), ntohl(tcphd->AckNumber));
  184.             if(filelog) fprintf(file,"  SeqNumber: %i \n  AckNumber: %i \n", ntohl(tcphd->SeqNumber), ntohl(tcphd->AckNumber));
  185.             
  186.             //calculate data offset and length
  187.             int data_start = ((ntohs(tcphd->Off_Res_Ctrl)>>12)-5)*4;
  188.             int data_end = ntohs(iphdr->Total_len) - iphdrlen - 20 - data_start;
  189.             printf("  Data Dump (%i): \n",data_end);
  190.             if(filelog) fprintf(file,"  Data Dump (%i): \n",data_end);
  191.  
  192.             //get data bytes
  193.             for(int j=data_start;j<data_end;j++) {
  194.                 if(!hexlog) printf("%c",tcphd->dati[j]);
  195.                 else {printf("%X ",tcphd->dati[j]);
  196.                       if(j%16==0 && j!=0) printf("\n");}
  197.                 
  198.                 if(filelog) {
  199.                     if(!hexlog) fprintf(file,"%c",tcphd->dati[j]);
  200.                     else {fprintf(file, "%X ",tcphd->dati[j]);
  201.                           if(j%16==0 && j!=0) fprintf(file,"\n");}
  202.                 }
  203.                 }
  204.             printf("\n");
  205.             }
  206.         }
  207.         break;
  208.  
  209.     
  210.     case 17:
  211.         printf("* [Protocol: UDP] \n");
  212.         if (filelog) fprintf(file,"* [Protocol: UDP] \n");
  213.  
  214.         if(filter_type==4 || filter_type==2) {
  215.         if (Size > iphdrlen)
  216.         {
  217.             //Analyze UDP
  218.             udphd = (UdpHeader *)(Buffer + iphdrlen);
  219.             
  220.             printf("  SrcPort: %i  =>  ", ntohs(udphd->SrcPort));
  221.             if (filelog) fprintf(file,"  SrcPort: %i  =>  ", ntohs(udphd->SrcPort));
  222.  
  223.             //try to guess upper-layer protocol looking src port number            
  224.             if(ntohs(udphd->SrcPort)==53)  {printf("(DNS)"); if(filelog) fprintf(file,"(DNS)");}
  225.             if(ntohs(udphd->SrcPort)==137)  {printf("(NetBIOS)"); if(filelog) fprintf(file,"(NetBIOS)");}
  226.  
  227.             printf("\n  DstPort: %i \n", ntohs(udphd->DstPort));
  228.             if(filelog) fprintf(file,"\n  DstPort: %i \n", ntohs(udphd->DstPort));
  229.  
  230.             printf("  Length: %i \n", ntohs(udphd->Length));
  231.             if(filelog) fprintf(file,"  Length: %i \n", ntohs(udphd->Length));
  232.  
  233.             int data_start = 0;
  234.             int data_end = ntohs(udphd->Length) - 8;
  235.             printf("  Data Dump (%i): \n",data_end);
  236.             if(filelog) fprintf(file,"  Data Dump (%i): \n",data_end);
  237.  
  238.             for(int j=data_start;j<data_end;j++) {
  239.                 if(!hexlog) printf("%c",udphd->dati[j]);
  240.                 else {printf("%X ",udphd->dati[j]);
  241.                       if(j%16==0 && j!=0) printf("\n");}
  242.  
  243.                 if(filelog) {
  244.                     if(!hexlog) fprintf(file,"%c",udphd->dati[j]);
  245.                     else {fprintf(file, "%X ",udphd->dati[j]);
  246.                           if(j%16==0 && j!=0) fprintf(file,"\n");}
  247.                     }
  248.                 }
  249.             printf("\n");
  250.             }
  251.         }
  252.         break;
  253.  
  254.  
  255.     default:
  256.         printf("* [Protocol: %i ] \n", iphdr->Protocol); 
  257.         if (filelog) fprintf(file,"* [Protocol: %i ] \n", iphdr->Protocol); 
  258.     }
  259.  
  260.     printf("\n");
  261.     if(filelog) fprintf(file,"\n");
  262. }
  263.  
  264.  
  265. // SNIFFER LOOP
  266. void Sniffing(SOCKET Sock)
  267. {
  268.     char *RecvBuffer = (char *)malloc(MAX_PACKET_SIZE + 1);
  269.     int BytesRecv, FromLen;
  270.     struct sockaddr_in From;
  271.  
  272.     if (RecvBuffer == NULL)
  273.     {    printf("malloc() failed.\n");
  274.         exit(-1);
  275.     }
  276.  
  277.     FromLen = sizeof(From);
  278.  
  279.     
  280.     //packet-capture loop
  281.     do
  282.     {
  283.         memset(RecvBuffer, 0, MAX_PACKET_SIZE + 1);
  284.         memset(&From, 0, sizeof(From));
  285.  
  286.         BytesRecv = recvfrom(Sock, RecvBuffer, MAX_PACKET_SIZE, 0, (sockaddr *)&From, &FromLen);
  287.         
  288.         //capture a packet and pass it to filtering function
  289.         if (BytesRecv > 0)
  290.         {    PacketFilter(RecvBuffer, BytesRecv);}
  291.         else
  292.         {    printf( "recvfrom() failed.\n");}
  293.  
  294.     } while (BytesRecv > 0);
  295.  
  296.  
  297.     free(RecvBuffer);
  298. }
  299.  
  300.  
  301. // MAIN PROGRAM
  302. // - NETWORK CARD SETUP
  303. // - RAW SOCKET BINDING
  304. int main()
  305. {
  306.     WSAData wsaData;
  307.     SOCKET Sock;
  308.     struct sockaddr_in SockAddr;
  309.     DWORD BytesReturned;
  310.     int I = 1;
  311.     int sfres,sfsel;
  312.  
  313.     try
  314.     {
  315.         if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0)
  316.         {    printf("Error: WSAStartup() failed\n");
  317.             exit(-1);
  318.         }
  319.  
  320.         Sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
  321.  
  322.         if (Sock == INVALID_SOCKET)
  323.         {    printf("Error: socket() failed\n");
  324.             exit(-1);
  325.         }
  326.  
  327.         memset(&SockAddr, 0, sizeof(SockAddr));
  328.  
  329.         printf("\nSIMPLE PACKET SNIFFER\n");
  330.         printf("---------------------  \n");
  331.         printf("Written by Elia Florio \n");
  332.         printf("(eflorio@edmaster.it)  \n\n");
  333.         printf("Local IP Adrress  ? ");
  334.         sfres = scanf("%s",&ipaddr);
  335.  
  336.         SockAddr.sin_addr.s_addr = inet_addr(ipaddr);
  337.         SockAddr.sin_family = AF_INET;
  338.         SockAddr.sin_port = htons(0); //anything...
  339.  
  340.         //binding socket in PROMISCUOUS MODE
  341.         if (bind(Sock, (SOCKADDR *)&SockAddr, sizeof(SockAddr)) == SOCKET_ERROR)
  342.             {    printf("Error: bind(%s) failed\n", inet_ntoa(SockAddr.sin_addr));
  343.                 exit(-1);
  344.             }
  345.         
  346.         if (WSAIoctl(Sock, SIO_RCVALL, &I, sizeof(I), NULL, NULL, &BytesReturned, NULL, NULL) == SOCKET_ERROR)
  347.         {    printf("Error: WSAIoctl() failed\n");
  348.             exit(-1);
  349.         }
  350.  
  351.         printf("\n1) Log immediato solo su console\n");
  352.         printf("2) Log su console e su file (C:\\SPSLOG.TXT)\n");
  353.         printf("Modalita' di logging ? ");
  354.         sfres = scanf("%d",&sfsel);
  355.         if (sfsel==1) filelog=false;
  356.         else filelog=true;
  357.  
  358.         printf("\n1) Dump in formato ASCII leggibile\n");
  359.         printf("2) Dump in formato HEX\n");
  360.         printf("Modalita' di dump ? ");
  361.         sfres = scanf("%d",&sfsel);
  362.         if (sfsel==1) hexlog=false;
  363.         else hexlog=true;
  364.  
  365.         printf("\n1) TCP\n");
  366.         printf("2) UDP\n");
  367.         printf("3) ICMP\n");
  368.         printf("4) TCP / UDP / ICMP\n");
  369.         printf("Pacchetti da analizzare ? ");
  370.         sfres = scanf("%d",&filter_type);
  371.         
  372.         printf("\n\n\n\n\n-------------------------------------------BEGIN SESSION\n");
  373.         
  374.         if (filelog) {
  375.             filename="C:\\SPSLOG.TXT";
  376.             file=fopen(filename,"a+");
  377.             fprintf(file,"\n-------------------------------------------BEGIN SESSION\n");
  378.         }
  379.         
  380.         Sniffing(Sock);
  381.     }
  382.     
  383.     catch (...)
  384.     {
  385.         printf("Error: Unknown exception\n");
  386.     }
  387.  
  388.     closesocket(Sock);
  389.     WSACleanup();
  390.  
  391.     return 0;
  392. }
  393.