简体   繁体   English

c#中的UDP数据包捕获

[英]UDP packet capturing in c#

Wireshark captures UDP packets in my LAN with follwoing details Wireshark使用以下详细信息捕获LAN中的UDP数据包

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#? 我怎样才能在c#中捕获它?

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];
        }
    }

}

The Winpcap library is one of the best ways to do this. Winpcap库是执行此操作的最佳方法之一。 I have experience in doing this in C# and it was really easy to work with this library. 我有使用C#这样做的经验,并且使用这个库非常容易。

This project shows how to do it with C#. 项目展示了如何使用C#完成它。

Wireshark actually uses Winpcap to do this, and as the other answer indicates, you can use it as well. Wireshark实际上使用Winpcap来做到这一点,正如另一个答案所示,你也可以使用它。

You can also use the System.Net.Sockets.Socket class and place it in promiscuous mode. 您还可以使用System.Net.Sockets.Socket类并将其置于混杂模式。 I use this to capture the IP traffic (eg, TCP and UDP) from a given network interface. 我用它来从给定的网络接口捕获IP流量(例如,TCP和UDP)。 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. 现在已经创建并配置了套接字,您可以使用Receive()方法开始接收数据。 Each time you call Receive() , the returned buffer will contain an IP packet. 每次调用Receive() ,返回的缓冲区都将包含一个IP数据包。 See here for the breakout of the IPv4 header, here for the UDP header, and here for the TCP header. 有关IPv4标头的详细信息,请参见此处此处为UDP标头, 此处为TCP标头。 If the Protocol field of the IP header contains a value of 17, then you have a UDP packet. 如果IP标头的Protocol字段包含值17,那么您有一个UDP数据包。

NOTE Raw sockets on Windows require that you be an administrator on your local system. 注意 Windows上的原始套接字要求您是本地系统的管理员。 The following language is contained in this MSDN article . MSDN文章中包含以下语言。

To use a socket of type SOCK_RAW requires administrative privileges. 要使用SOCK_RAW类型的套接字,需要管理权限。 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. 运行使用原始套接字的Winsock应用程序的用户必须是本地计算机上Administrators组的成员,否则原始套接字调用将失败,错误代码为WSAEACCES。 On Windows Vista and later, access for raw sockets is enforced at socket creation. 在Windows Vista及更高版本中,在创建套接字时强制访问原始套接字。 In earlier versions of Windows, access for raw sockets is enforced during other socket operations. 在早期版本的Windows中,在其他套接字操作期间强制访问原始套接字。

In order to use WinPcap for raw packet capturing in C#, you can try Pcap.Net . 为了在C#中使用WinPcap进行原始数据包捕获,您可以尝试使用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. 它是C ++ / CLI和C#中的WinPcap的包装器,用于轻松捕获(嗅探)和注入原始数据包,它还包含一个易于使用的数据包解释框架。

Using Pcap.Net in https://github.com/PcapDotNet https://github.com/PcapDotNet中使用Pcap.Net

Especific exemple: https://github.com/PcapDotNet/Pcap.Net/wiki/Pcap.Net-Tutorial-Interpreting-the-packets 具体例子: https//github.com/PcapDotNet/Pcap.Net/wiki/Pcap.Net-Tutorial-Interpreting-the-packets

// Callback function invoked by libpcap for every incoming packet
    private static void PacketHandler(Packet packet)
    {
        // print timestamp and length of the packet
        Console.WriteLine(packet.Timestamp.ToString("yyyy-MM-dd hh:mm:ss.fff") + " length:" + packet.Length);

        IpV4Datagram ip = packet.Ethernet.IpV4;
        UdpDatagram udp = ip.Udp;

        // print ip addresses and udp ports
        Console.WriteLine(ip.Source + ":" + udp.SourcePort+ " -> " + ip.Destination + ":" + udp.DestinationPort);
    }

Output: 2009-09-12 11:25:51.117 length:84 10.0.0.8:49003 -> 208.67.222.222:53 2009-09-12 11:25:51.212 length:125 208.67.222.222:53 -> 10.0.0.8:49003 2009-09-12 11:25:54.323 length:80 10.0.0.8:39209 -> 208.67.222.222:53 2009-09-12 11:25:54.426 length:75 10.0.0.8:47869 -> 208.67.222.222:53 2009-09-12 11:25:54.517 length:236 208.67.222.222:53 -> 10.0.0.8:39209 2009-09-12 11:25:54.621 length:91 208.67.222.222:53 -> 10.0.0.8:47869 输出: 2009-09-12 11:25:51.117 length:84 10.0.0.8:49003 -> 208.67.222.222:53 2009-09-12 11:25:51.212 length:125 208.67.222.222:53 -> 10.0.0.8:49003 2009-09-12 11:25:54.323 length:80 10.0.0.8:39209 -> 208.67.222.222:53 2009-09-12 11:25:54.426 length:75 10.0.0.8:47869 -> 208.67.222.222:53 2009-09-12 11:25:54.517 length:236 208.67.222.222:53 -> 10.0.0.8:39209 2009-09-12 11:25:54.621 length:91 208.67.222.222:53 -> 10.0.0.8:47869

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM