Results 1 to 2 of 2
  1. #1
    Dwar
    Dwar is offline
    Veteran Dwar's Avatar
    Join Date
    2010 Mar
    Posts
    2,222
    Thanks Thanks Given 
    211
    Thanks Thanks Received 
    2,230
    Thanked in
    292 Posts
    Rep Power
    10

    Creating Simple Network Sniffer

    This article describes the process of creating a simple network sniffer which can parse IP, TCP, UDP, and DNS packets.

    Capturing the Packets
    Code:
    // For sniffing the socket to capture the packets 
    // has to be a raw socket, with the address family
    // being of type internetwork, and protocol being IP
    mainSocket = newSocket(AddressFamily.InterNetwork, SocketType.Raw,
                           ProtocolType.IP);
    
    // Bind the socket to the selected IP address
    mainSocket.Bind(newIPEndPoint(IPAddress.Parse(cmbInterfaces.Text),0));
    
    // Set the socket options
    mainSocket.SetSocketOption(SocketOptionLevel.IP,  //Applies only to IP packets
                               SocketOptionName.HeaderIncluded, //Set the include header
                               true);                           //option to true
    
    byte[] byTrue = newbyte[4]{1, 0, 0, 0};
    byte[] byOut = newbyte[4];
    
    //Socket.IOControl is analogous to the WSAIoctl method of Winsock 2
    mainSocket.IOControl(IOControlCode.ReceiveAll,  //SIO_RCVALL of Winsock
                         byTrue, byOut);
    
    //Start receiving the packets asynchronously
    mainSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
                            newAsyncCallback(OnReceive), null);
    For capturing the packets, we use a raw socket and bind it to the IP address. After setting the proper options for the socket, we then call the IOControl method on it. Notice that IOControl is analogous to the Winsock2WSAIoctl method. The IOControlCode.ReceiveAll implies that all incoming and outgoing packets on the particular interface be captured.
    The second parameter passed to IOControl with IOControlCode.ReceiveAll should be TRUE so an array byTrue is created and passed to it (thanks to Leonid Molochniy for this). Next we start receiving all packets asynchronously.


    Analysing the Packets

    The IP datagram encapsulates the TCP and UDP packets. This further contains the data sent by the application layer protocols such as DNS, HTTP, FTP, SMTP, SIP, etc. Thus a TCP packet is received inside the IP datagram, like this:
    Code:
    +-----------+------------+--------------------+
    | IP header | TCP header |        Data        |  
    +-----------+------------+--------------------+
    So the first thing that we need to do is to parse the IP header. The stripped version of the IP header class is shown below, the comments describe the things as they happen.
    Code:
    public classIPHeader 
    { 
      //IP Header fields 
      private byte byVersionAndHeaderLength; // Eight bits for version and header 
                                             // length 
      private byte byDifferentiatedServices; // Eight bits for differentiated 
                                             // services
      private ushort usTotalLength;          // Sixteen bits for total length 
      private ushort usIdentification;       // Sixteen bits for identification
      private ushort usFlagsAndOffset;       // Eight bits for flags and frag. 
                                             // offset 
      private byte byTTL;                    // Eight bits for TTL (Time To Live) 
      private byte byProtocol;               // Eight bits for the underlying 
                                             // protocol 
      private short sChecksum;               // Sixteen bits for checksum of the 
                                             //  header 
      private uint uiSourceIPAddress;        // Thirty two bit source IP Address 
      private uint uiDestinationIPAddress;   // Thirty two bit destination IP Address 
    
      //End IP Header fields   
      private byte byHeaderLength;             //Header length 
      private byte[] byIPData = new byte[4096]; //Data carried by the datagram
      public IPHeader(byte[] byBuffer, int nReceived)
      {
        try
        {
        //Create MemoryStream out of the received bytes
        MemoryStream memoryStream = newMemoryStream(byBuffer, 0, nReceived);
        
        //Next we create a BinaryReader out of the MemoryStream
        BinaryReader binaryReader = newBinaryReader(memoryStream);
    
        //The first eight bits of the IP header contain the version and
        //header length so we read them
        byVersionAndHeaderLength = binaryReader.ReadByte();
    
        //The next eight bits contain the Differentiated services
        byDifferentiatedServices = binaryReader.ReadByte();
        
        //Next eight bits hold the total length of the datagram
        usTotalLength = 
                 (ushort) IPAddress.NetworkToHostOrder(binaryReader.ReadInt16());
    
        //Next sixteen have the identification bytes
        usIdentification = 
                  (ushort)IPAddress.NetworkToHostOrder(binaryReader.ReadInt16());
    
        //Next sixteen bits contain the flags and fragmentation offset
        usFlagsAndOffset = 
                  (ushort)IPAddress.NetworkToHostOrder(binaryReader.ReadInt16());
    
        //Next eight bits have the TTL value
        byTTL = binaryReader.ReadByte();
    
        //Next eight represent the protocol encapsulated in the datagram
        byProtocol = binaryReader.ReadByte();
    
        //Next sixteen bits contain the checksum of the header
        sChecksum = IPAddress.NetworkToHostOrder(binaryReader.ReadInt16());
    
        //Next thirty two bits have the source IP address
        uiSourceIPAddress = (uint)(binaryReader.ReadInt32());
    
        //Next thirty two hold the destination IP address
        uiDestinationIPAddress = (uint)(binaryReader.ReadInt32());
    
        //Now we calculate the header length
        byHeaderLength = byVersionAndHeaderLength;
    
        //The last four bits of the version and header length field contain the
        //header length, we perform some simple binary arithmetic operations to
        //extract them
        byHeaderLength <<= 4;
        byHeaderLength >>= 4;
    
        //Multiply by four to get the exact header length
        byHeaderLength *= 4;
    
        //Copy the data carried by the datagram into another array so that
        //according to the protocol being carried in the IP datagram
        Array.Copy(byBuffer, 
                   byHeaderLength, //start copying from the end of the header
                   byIPData, 0, usTotalLength - byHeaderLength);
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "MJsniff", MessageBoxButtons.OK, 
                            MessageBoxIcon.Error);
        }
     }
    //Please see the attached codes for the properties…
    }
    Firstly, the class contains the data members corresponding to the fields of the IP header. Kindly see RFC 791 for a detailed explanation of the IP header and its fields. The constructor of the class takes the bytes received and creates a MemoryStream on the received bytes and then creates a BinaryReader to read the data from the MemoryStream byte-by-byte. Also note that the data received from the network is in big-endian form so we use the IPAddress.NetworkToHostOrder to correct the byte ordering. This has to be done for all non-byte data members.
    The TCP, UDP headers are also parsed in an identical fashion, the only difference is that they are read from the point where the IP header ends. As an example of parsing the application layer protocols, the attached project can detect DNS packets as well.

    Please register or login to download attachments.

    Please, post your questions on forum, not by PM or mail

    I spend my time, so please pay a little bit of your time to keep world in equilibrium

  2. The Following User Says Thank You to Dwar For This Useful Post:


  3. #2
    goatboat
    goatboat is offline
    Guest
    Join Date
    2017 Apr
    Posts
    1
    Thanks Thanks Given 
    0
    Thanks Thanks Received 
    0
    Thanked in
    0 Posts
    Rep Power
    0
    I've searched quite a bit for a complete example, thanks for the submission!

Similar Threads

  1. [C#] WinPCap Packet Sniffer Source
    By Dwar in forum VB, .NET Framework
    Replies: 2
    Last Post: 2014-08-24, 07:47 PM
  2. [C#] Simple Packet Sniffer Source
    By Dwar in forum VB, .NET Framework
    Replies: 0
    Last Post: 2012-08-23, 10:01 AM
  3. [Delphi] Creating a Simple Game Trainer
    By Dwar in forum Delphi
    Replies: 21
    Last Post: 2012-07-24, 02:38 PM
  4. [Network Traffic Analyzer] Wireshark formerly Ethereal
    By wildspirit in forum Files & Tools
    Replies: 0
    Last Post: 2011-11-05, 06:45 AM
  5. [MASM] Creating a Simple Hack
    By Dwar in forum Programming Tutorials
    Replies: 0
    Last Post: 2010-11-29, 04:03 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •