C#中的UDP数据包捕获
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2271183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UDP packet capturing in c#
提问by Manjoor
Wireshark captures UDP packets in my LAN with follwoing details
Wireshark 使用以下详细信息捕获我局域网中的 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# 中捕获它?
采纳答案by Manjoor
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];
}
}
}
回答by Chathuranga Chandrasekara
回答by Matt Davis
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. I use this to capture the IP traffic (e.g., TCP and UDP) from a given network interface. Here's an example.
您还可以使用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);
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 herefor the breakout of the IPv4 header, herefor the UDP header, and herefor the TCP header. If the Protocolfield of the IP header contains a value of 17, then you have a UDP packet.
现在套接字已创建并配置好,您可以使用该Receive()
方法开始接收数据。每次调用时Receive()
,返回的缓冲区将包含一个 IP 数据包。请参阅此处了解 IPv4 标头的突破,此处了解 UDP 标头,以及此处了解 TCP 标头。如果IP 标头的协议字段包含值 17,则您有一个 UDP 数据包。
NOTERaw sockets on Windows require that you be an administrator on your local system. The following language is contained in this MSDN article.
注意Windows 上的原始套接字要求您是本地系统的管理员。此MSDN 文章中包含以下语言。
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.
要使用 SOCK_RAW 类型的套接字需要管理权限。运行使用原始套接字的 Winsock 应用程序的用户必须是本地计算机上 Administrators 组的成员,否则原始套接字调用将失败,错误代码为 WSAEACCES。在 Windows Vista 和更高版本上,对原始套接字的访问是在创建套接字时强制执行的。在早期版本的 Windows 中,对原始套接字的访问是在其他套接字操作期间强制执行的。
回答by brickner
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.
为了在 C# 中使用 WinPcap 进行原始数据包捕获,您可以尝试Pcap.Net。它是 C++/CLI 和 C# 中 WinPcap 的包装器,用于轻松捕获(嗅探)和注入原始数据包,它还包含一个易于使用的数据包解释框架。
回答by williambarau
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