c#中的UDP数据包捕获

时间:2010-02-16 07:13:59

标签: c# sockets udp

Wireshark通过以下详细信息捕获局域网中的UDP数据包

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

如何在c#中捕获它?

5 个答案:

答案 0 :(得分:10)

自己解决了

这是我的工作代码

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

}

答案 1 :(得分:7)

Winpcap库是执行此操作的最佳方法之一。我有使用C#这样做的经验,使用这个库真的很容易。

这个project显示了如何使用C#。

答案 2 :(得分:6)

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标头的分组,请参阅here,对于UDP标头,请参阅here,对于TCP标头,请参阅here。如果IP标头的 Protocol 字段包含值17,那么您有一个UDP数据包。

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

  

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

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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