Thread
Print

Network sniffer and Connection Analyzer

Network sniffer and Connection Analyzer

Using the code

using System;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
//using System.Diagnostics;
using System.Collections;

namespace Sniffer
{
public delegate void IPv4DatagramCallback(IPv4Datagram datagram);
public delegate void IPv4FragmentCallback(IPv4Fragment fragment);
public delegate void SnifferErrorCallback(SnifferException e);
public delegate void ConnectionCallback(IPEndPoint source, IPEndPoint destination);

/// <summary>
/// Summary description for SnifferSocket.
/// </summary>
public class SnifferSocket
{
  private Hashtable     SocketMap_  = null;
  private DataManager   Data_       = null;
  private string IP="";
  private bool paused=false;

  public ArrayList IPs=null;
  public event IPv4DatagramCallback IPv4DatagramReceived;
  public event IPv4FragmentCallback IPv4FragmentReceived;
  public event SnifferErrorCallback SnifferError;
  
  // Creates a new SnifferSocket.
  public SnifferSocket() {
   Data_ = new DataManager();
   SocketMap_ = new Hashtable();
   IPs=new ArrayList();
  }

  public bool Pause
  {
   get { return paused; }
   set { paused = value; }
  }


  // This will start the Sniffer so that it will listen the IP passed in.
  // All of the Sniffing is done asynchronously so this method will return immediately.  
  public void Sniff(String ip)
  {
   IP=ip;
   Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Raw,ProtocolType.IP);
   byte[] buffer = new byte[2048];
   SocketPair socketpair = new SocketPair(socket,buffer);
   socket.Blocking = true;
   try
   {
    socket.Bind(new IPEndPoint(IPAddress.Parse(ip),0));
   }
   catch(SocketException e)
   {
    throw new SnifferException("Cannot assign requested address.The requested address is not valid in its context.",e);
   }
   this.SetupSocket(socket);
   
   if ( SocketMap_.Contains(ip) )
   {
    throw new SnifferException("Socket already bound on that IP");
   }
   else
   {
    SocketMap_.Add(ip,socketpair);
   }
   try
   {
    socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,new AsyncCallback(this.ReceivePacket),socketpair);
    paused=false;
   }
   catch ( Exception e )
   {
    throw new SnifferException("Could not start the Receive",e);
   }
  }


  //set up Socket to recieve all.
  private void SetupSocket(Socket socket) {
   bool ret_val = true;
   SocketException e = null;
   try {
    socket.SetSocketOption(SocketOptionLevel.IP,SocketOptionName.HeaderIncluded,1);
    byte []IN = new byte[4]{1, 0, 0, 0};
    byte []OUT = new byte[4];
    int SIO_RCVALL = unchecked((int)0x98000001);
    int ret_code = socket.IOControl(SIO_RCVALL, IN, OUT);
    ret_code = OUT[0] + OUT[1] + OUT[2] + OUT[3];
    if(ret_code != 0)
     ret_val = false;
   } catch ( SocketException ex ) {
    e = ex;
    ret_val = false;
   } finally {
    if ( ! ret_val ) {
     throw new SnifferException("Could not set the socket to receive all",e);
    }
   }

  }

  public void resumeSocket()
  {
   SocketPair p = SocketMap_[IP] as SocketPair;
   Socket socket = p.IPSocket;
   bool ret_val = true;
   SocketException e = null;
   try
   {
    socket.BeginReceive(p.Buffer,0,p.Buffer.Length,SocketFlags.None,new AsyncCallback(this.ReceivePacket),p);
    this.paused=false;
   }
   catch ( SocketException ex )
   {
    e = ex;
    ret_val = false;
   }
   finally
   {
    if ( ! ret_val )
    {
     throw new SnifferException("Could not resume the socket",e);
    }
   }
  }
  
  // Callback function for the Asynchronous Receive on a Socket.
  private void ReceivePacket(IAsyncResult ar)
  {
   bool fired=false;
   int len = 0;
   SocketPair p = ar.AsyncState as SocketPair;
   Socket socket = p.IPSocket;
   int type = 0;
   try
   {
    len = socket.EndReceive(ar);
   }
   catch ( SocketException e)
   {
    fired = true;
    FireSnifferError(new SnifferException("Error Receiving Packet",e));
   }

   if (!fired)
   {
    type = HeaderParser.ToInt(p.Buffer,0,4);
    try
    {
     switch(type)
     {
      case 4:
       HandleIPv4Datagram(p.Buffer);
       break;
     }
    }
    catch ( Exception e )
    {
     FireSnifferError(new SnifferException(e.Message.ToString(),e));
    }
   }
   if (!this.paused)
   {
    socket.BeginReceive(p.Buffer,0,p.Buffer.Length,SocketFlags.None,new AsyncCallback(this.ReceivePacket),p);
   }
  }

  // Parses out an IPv4 Datagram.  
  private void HandleIPv4Datagram(byte[] buffer) {
   int identification = 0;
   int protocol = 0;
   uint source = 0;
   uint dest   = 0;
   int header_length = 0;
   IPv4Datagram datagram = null;
   IPAddress source_ip;
   IPAddress dest_ip;


   source = HeaderParser.ToUInt(buffer,96,32);
   dest = HeaderParser.ToUInt(buffer,128,32);
   source_ip = IPAddress.Parse(IPv4Datagram.GetIPString(source));
   dest_ip = IPAddress.Parse(IPv4Datagram.GetIPString(dest));
   if (isRelatedToThisCom(source_ip.ToString(),dest_ip.ToString()))
   {

    IPv4Fragment fragment = new IPv4Fragment();

    fragment.MoreFlag = (HeaderParser.ToByte(buffer,50,1) > 0) ? true : false;
    fragment.Offset = HeaderParser.ToInt(buffer,51,13) * 8;
    fragment.TTL = HeaderParser.ToInt(buffer,64,8);
    fragment.Length  = HeaderParser.ToUShort(buffer,16,16);
    header_length = HeaderParser.ToInt(buffer,4,4) * 4;
    fragment.SetData(buffer,header_length,fragment.Length - header_length);

    identification = HeaderParser.ToInt(buffer,32,16);
    protocol = HeaderParser.ToByte(buffer,72,8);
//    source = HeaderParser.ToUInt(buffer,96,32);
//    dest = HeaderParser.ToUInt(buffer,128,32);
//    source_ip = IPAddress.Parse(IPv4Datagram.GetIPString(source));
//    dest_ip = IPAddress.Parse(IPv4Datagram.GetIPString(dest));
   
    datagram = Data_.GetIPv4Datagram(identification,source_ip,dest_ip);

    if ( datagram == null )
    {
     datagram = new IPv4Datagram();
     datagram.IHL = HeaderParser.ToInt(buffer,4,4) * 4;
     datagram.TypeOfService = HeaderParser.ToInt(buffer,8,8);
     datagram.ReservedFlag = HeaderParser.ToInt(buffer,48,1);
     datagram.DontFragmentFlag = HeaderParser.ToInt(buffer,49,1);
     datagram.Identification = identification;
     datagram.TTL = HeaderParser.ToInt(buffer,64,8);
     datagram.Checksum = HeaderParser.ToInt(buffer,80,16);
     datagram.Source = source_ip;
   
     datagram.SourceName=DnsTable.GetName(source_ip.ToString());

     datagram.DestinationName=DnsTable.GetName(dest_ip.ToString());

     datagram.Destination = dest_ip;
     datagram.Protocol = protocol;
     if (datagram.IHL==24)
      datagram.Options = HeaderParser.ToInt(buffer,160,32);

    }

    datagram.AddFragment(fragment);
    if ( datagram.Complete )
    {
     datagram.SetPorts();
     if (FilterManager.isAllowed(datagram.GetUpperProtocol(),datagram.SourceIP,datagram.DestinationIP,datagram.SPort,datagram.DPort))
     {
      FireIPv4DatagramReceived(datagram);

      datagram.SetHeader(buffer);
      if ( datagram.WasFragmented() )
      {
       Data_.RemoveIPv4Datagram(datagram);
      }
     }
    }
    else
    {
     Data_.AddIPv4Datagram(datagram);
     this.FireIPv4FragmentReceived(fragment);
    }
   }

  }

  private void FireSnifferError(SnifferException e ) {
   if ( SnifferError != null ) {
    SnifferError(e);
   }
  }

  // This will fire a IPv4DatagramReceived event.
  private void FireIPv4DatagramReceived(IPv4Datagram datagram) {
   if (IPv4DatagramReceived != null ) {
    IPv4DatagramReceived(datagram);
   }
  }

  // This will fire a IPv4FragmentReceived event
  private void FireIPv4FragmentReceived(IPv4Fragment fragment) {
   
   if (IPv4FragmentReceived != null ) {
    IPv4FragmentReceived(fragment);
   }
  }

  private bool isRelatedToThisCom(string srcIp,string destIp)
  {
   return (IPs.Contains(srcIp)||IPs.Contains(destIp));
  }
}
}

Attachment

HSSniffer.zip (495.31 KB)

3-9-2008 15:03, Downloaded count: 103

TOP

Thread