tags:

views:

1421

answers:

4

Wireshark captures UDP packets in my LAN with follwoing details

Source IP            192.168.1.2
Destination IP      233.x.x.x
Source Port        24098
Destination Port      12074,12330

how can i capture it in c#?

+3  A: 

The Winpcap library is one of the best ways to do this. I have experience in doing this in C# and it was really easy to work with this library.

This project shows how to do it with C#.

Chathuranga Chandrasekara
I think you mean http://www.tamirgal.com/blog/page/SharpPcap.aspx SharpPCap ;-)
weismat
Its WinPcap. Follow the above link. I think SharpPCap is a wrapped version and perhaps it will be more convenient to use.
Chathuranga Chandrasekara
Above is a multicast stream. Can i use simple .Net sockett classes to retrieve packets???
Manjoor
I think so.. Try this...http://www.codeproject.com/KB/IP/multicast.aspx
Chathuranga Chandrasekara
I tried it but no luck :(
Manjoor
Using .NET classes such as UdpClient and TcpClient will ***not*** return the source and destination information you're looking for. These sockets only return you the payload when you receive data from them. The `LocalEndPoint` and `RemoteEndPoint` properties of the `Socket` class will work for TCP-based communication. But for UDP, the `RemoteEndPoint` is not always what you want. The source and destination addresses are contained in the IP header and the ports are in the TCP/UDP headers. To get this data using a .NET socket, you have to collect using a "raw" socket.
Matt Davis
+1  A: 

Wireshark actually uses Winpcap to do this, and as the other answer indicates, you can use it as well.

You can also use the System.Net.Sockets.Socket class and place it in promiscuous mode. I use this to capture the IP traffic (e.g., TCP and UDP) from a given network interface. Here's an example.

using System.Net;
using System.Net.Sockets;

Socket socket =
    new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.IP);
socket.Bind(new IPEndPoint(IPAddress.Parse("X.X.X.X"), 0)); // specify IP address
socket.ReceiveBufferSize = 2 * 1024 * 1024; // 2 megabytes
socket.ReceiveTimeout = 500; // half a second
byte[] incoming = BitConverter.GetBytes(1);
byte[] outgoing = BitConverter.GetBytes(1);
socket.IOControl(IOControlCode.ReceiveAll, incoming, outgoing);

Now that the socket is created and configured, you can use the Receive() method to start receiving data. Each time you call Receive(), the returned buffer will contain an IP packet. See here for the breakout of the IPv4 header, here for the UDP header, and here for the TCP header. If the Protocol field of the IP header contains a value of 17, then you have a UDP packet.

NOTE Raw sockets on Windows require that you be an administrator on your local system. The following language is contained in this MSDN article.

To use a socket of type SOCK_RAW requires administrative privileges. Users running Winsock applications that use raw sockets must be a member of the Administrators group on the local computer, otherwise raw socket calls will fail with an error code of WSAEACCES. On Windows Vista and later, access for raw sockets is enforced at socket creation. In earlier versions of Windows, access for raw sockets is enforced during other socket operations.

Matt Davis
Thanks for reply. I am checking it. Meanwhile note that that above is a multicast stream (UDP).
Manjoor
above code gives exception"An attempt was made to access a socket in a way forbidden by its access permissions"
Manjoor
I forgot to mention that you have to have admin privileges on your local machine to create a "raw" socket like this. I'm running this code inside a Windows service which is running under the SYSTEM account, so this issue doesn't bite me. Also, if you are doing multicast UDP, creating a socket this way does **not** join the multicast group. Thus, if you are behind a router, you are not guaranteed that the multicast traffic will be routed along the segment you're on. In short, you may want to join the multicast group with a second socket to ensure that this "raw" socket will see the data.
Matt Davis
A: 

Solved it myself

Here is my working code

class CAA
{

    private Socket UDPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    private IPAddress Target_IP;
    private int Target_Port;
    public static int bPause;

    public CAA()
    {
        Target_IP = IPAddress.Parse("x.x.x.x");
        Target_Port = xxx;

        try
        {
            IPEndPoint LocalHostIPEnd = new
            IPEndPoint(IPAddress.Any, Target_Port);
            UDPSocket.SetSocketOption(SocketOptionLevel.Udp, SocketOptionName.NoDelay, 1);
            UDPSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
            UDPSocket.Bind(LocalHostIPEnd);
            UDPSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 0);
            UDPSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new
            MulticastOption(Target_IP));
            Console.WriteLine("Starting Recieve");
            Recieve();
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message + " " + e.StackTrace);
        }
    }

    private void Recieve()
    {
        try
        {
            IPEndPoint LocalIPEndPoint = new
            IPEndPoint(IPAddress.Any, Target_Port);
            EndPoint LocalEndPoint = (EndPoint)LocalIPEndPoint;
            StateObject state = new StateObject();
            state.workSocket = UDPSocket;
            Console.WriteLine("Begin Recieve");
            UDPSocket.BeginReceiveFrom(state.buffer, 0, state.BufferSize, 0, ref LocalEndPoint, new AsyncCallback(ReceiveCallback), state);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.ToString());
        }
    }

    private void ReceiveCallback(IAsyncResult ar)
    {

            IPEndPoint LocalIPEndPoint = new
            IPEndPoint(IPAddress.Any, Target_Port);
            EndPoint LocalEndPoint = (EndPoint)LocalIPEndPoint;
            StateObject state = (StateObject)ar.AsyncState;
            Socket client = state.workSocket;
            int bytesRead = client.EndReceiveFrom(ar, ref LocalEndPoint);            



            client.BeginReceiveFrom(state.buffer, 0, state.BufferSize, 0, ref LocalEndPoint, new AsyncCallback(ReceiveCallback), state);
    }


    public static void Main()
    {       
        CAA o = new CAA();        
        Console.ReadLine();
    }

    public class StateObject
    {
        public int BufferSize = 512;
        public Socket workSocket;
        public byte[] buffer;

        public StateObject()
        {
            buffer = new byte[BufferSize];
        }
    }

}
Manjoor
A: 

In order to use WinPcap for raw packet capturing in C#, you can try Pcap.Net. It is a wrapper for WinPcap in C++/CLI and C# for easily capturing (sniffing) and injecting raw packets and it also contains an easy to use packets interpretation framework.

brickner