C#中的UDP数据包捕获

发布于 2024-08-21 15:34:18 字数 214 浏览 6 评论 0原文

Wireshark 在我的 LAN 中捕获 UDP 数据包,详细信息如下,

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

我如何在 C# 中捕获它?

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#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

ˇ宁静的妩媚 2024-08-28 15:34:18

我自己解决了

这是我的工作代码

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

}

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

}
浅浅 2024-08-28 15:34:18

Winpcap 库是实现此目的的最佳方法之一。我有使用 C# 执行此操作的经验,并且使用这个库非常容易。

项目展示了如何使用 C# 执行此操作。

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#.

白色秋天 2024-08-28 15:34:18

Wireshark 实际上使用 Winpcap 来执行此操作,正如其他答案所示,您也可以使用它。

您还可以使用 System.Net.Sockets.Socket 类并将其置于混杂模式。我用它来捕获来自给定网络接口的 IP 流量(例如 TCP 和 UDP)。这是一个例子。

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);

现在套接字已创建并配置完毕,您可以使用 Receive() 方法开始接收数据。每次调用Receive()时,返回的缓冲区将包含一个IP数据包。请参阅此处了解 IPv4 标头的详细信息,此处 为 UDP 标头,以及 这里为 TCP 标头。如果 IP 标头的协议字段包含值 17,则您有一个 UDP 数据包。

注意 Windows 上的原始套接字要求您是本地系统的管理员。此MSDN 文章中包含以下语言。

使用 SOCK_RAW 类型的套接字
需要管理权限。
运行 Winsock 应用程序的用户
使用原始套接字的必须是成员
管理员组的
本地计算机,否则原始套接字
调用将失败,错误代码为
WSAEACCES。在 Windows Vista 及更高版本上,
对原始套接字的访问强制执行于
套接字创建。在早期版本中
在 Windows 中,原始套接字的访问是
在其他套接字期间强制执行
操作。

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.

天生の放荡 2024-08-28 15:34:18

为了在 C# 中使用 WinPcap 进行原始数据包捕获,您可以尝试 Pcap.Net
它是 C++/CLI 和 C# 中 WinPcap 的包装器,用于轻松捕获(嗅探)和注入原始数据包,它还包含一个易于使用的数据包解释框架。

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.

萌逼全场 2024-08-28 15:34:18

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

具体示例: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);
    }

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

Using Pcap.Net in https://github.com/PcapDotNet

Especific exemple: 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文