SharpPcap是一个功能强大的.NET库,用于跨平台(Windows、Mac、Linux)的数据包捕获。本文将介绍SharpPcap的主要特性,并提供几个详细的应用示例。
主要特性
跨平台支持:
Linux: 支持libpcap
Windows: 支持Npcap和WinDivert
所有平台: 支持实时设备列表、统计信息、从实时设备和离线设备读取数据包
数据包处理:
支持Berkeley数据包过滤器
可以将数据包转储到Pcap文件
支持Pcap和pcap-ng格式(使用libpcap >=1.1.0或npcap时)
性能优化:
使用ReadOnlySpan<>避免内存分配和复制
提供辅助方法将捕获的数据包转换为对象实例
其他特性:
NativeLibrary支持,便于跨平台库解析
支持.NET Core 3和.NET Framework
应用示例
1. 列出可用的网络设备
using SharpPcap;class Program{static void Main(string[] args){获取所有可用的捕获设备var devices = CaptureDeviceList.Instance;打印每个设备的信息foreach (var dev in devices){Console.WriteLine($"设备: {dev.Name}");Console.WriteLine($"描述: {dev.Description}");Console.WriteLine();}}}

2. 捕获实时数据包
using SharpPcap;using SharpPcap.LibPcap;class Program{static void Main(string[] args){// 选择第一个可用的设备using var device = LibPcapLiveDeviceList.Instance[6];// 打开设备device.Open(DeviceModes.Promiscuous);// 设置过滤器(可选)device.Filter = "tcp";// 注册数据包到达事件处理程序device.OnPacketArrival += Device_OnPacketArrival;// 开始捕获device.StartCapture();Console.WriteLine("开始捕获数据包。按任意键停止...");Console.ReadKey();// 停止捕获device.StopCapture();}static void Device_OnPacketArrival(object sender, PacketCapture e){var packet = e.GetPacket();Console.WriteLine($"捕获到数据包: 长度 = {packet.Data.Length} 字节");Console.WriteLine($"时间戳: {packet.Timeval.Date}");Console.WriteLine($"数据: {BitConverter.ToString(packet.Data)}");Console.WriteLine();}}

3. 截获http的数据包
using System;using System.Text;using SharpPcap;using PacketDotNet;class Program{static void Main(string[] args){// 获取所有可用的捕获设备var devices = CaptureDeviceList.Instance;if (devices.Count < 1){Console.WriteLine("No devices found. Make sure WinPcap or Npcap is installed.");return;}// 选择第一个设备var device = devices[6];Console.WriteLine($"Capturing on {device.Description}");// 打开设备device.Open(DeviceModes.Promiscuous);// 设置过滤器,只捕获HTTP流量device.Filter = "tcp port 80 or tcp port 443";// 注册数据包到达事件处理程序device.OnPacketArrival += Device_OnPacketArrival;// 开始捕获device.StartCapture();Console.WriteLine("Capturing HTTP traffic. Press any key to stop...");Console.ReadKey();// 停止捕获device.StopCapture();device.Close();}static void Device_OnPacketArrival(object sender, PacketCapture e){var rawPacket = e.GetPacket();var packet = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);var tcpPacket = packet.Extract<TcpPacket>();if (tcpPacket != null){var ipPacket = (IPPacket)tcpPacket.ParentPacket;Console.WriteLine($"TCP Packet: {ipPacket.SourceAddress}:{tcpPacket.SourcePort} -> " +$"{ipPacket.DestinationAddress}:{tcpPacket.DestinationPort}");if (tcpPacket.PayloadData != null && tcpPacket.PayloadData.Length > 0){string payload = Encoding.ASCII.GetString(tcpPacket.PayloadData);if (payload.StartsWith("GET") || payload.StartsWith("POST") ||payload.StartsWith("HTTP/1.1") || payload.StartsWith("HTTP/1.0")){Console.WriteLine("HTTP Content:");Console.WriteLine(payload);Console.WriteLine();}}}}}

4. 写入捕获文件
using System;using SharpPcap;using PacketDotNet;class Program{static void Main(string[] args){// 获取第一个网络接口using var device = CaptureDeviceList.Instance[0];// 打开设备device.Open(mode: DeviceModes.Promiscuous, read_timeout: 1000);// 创建捕获文件写入器using var writer = new CaptureFileWriterDevice("capture.pcap");writer.Open(device);// 设置数据包到达事件处理device.OnPacketArrival += (sender, e) =>{writer.Write(e.GetPacket());Console.WriteLine("已写入一个数据包");};// 开始捕获device.StartCapture();Console.WriteLine("正在捕获数据包,按任意键停止...");Console.ReadKey();// 停止捕获device.StopCapture();}}

5. HTTP流量分析
using System;using System.Text;using PacketDotNet;using SharpPcap;class Program{static void Main(string[] args){// 获取第一个网络接口using var device = CaptureDeviceList.Instance[6];device.Open(mode: DeviceModes.Promiscuous, read_timeout: 1000);// 设置过滤器捕获HTTP和HTTPS流量device.Filter = "tcp port 80 or tcp port 443";device.OnPacketArrival += (sender, e) =>{var rawPacket = e.GetPacket();var packet = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);if (packet is EthernetPacket ethernetPacket){var ipPacket = ethernetPacket.PayloadPacket as IPPacket;var tcpPacket = ipPacket?.PayloadPacket as TcpPacket;if (tcpPacket != null && tcpPacket.PayloadData != null && tcpPacket.PayloadData.Length > 0){if (tcpPacket.DestinationPort == 80){AnalyzeHttpTraffic(tcpPacket);}else if (tcpPacket.DestinationPort == 443){AnalyzeHttpsTraffic(tcpPacket);}}}};device.StartCapture();Console.WriteLine("正在捕获HTTP和HTTPS流量,按任意键停止...");Console.ReadKey();device.StopCapture();}static void AnalyzeHttpTraffic(TcpPacket tcpPacket){string payload = Encoding.ASCII.GetString(tcpPacket.PayloadData);if (payload.StartsWith("GET") || payload.StartsWith("POST") || payload.StartsWith("PUT") || payload.StartsWith("DELETE")){string[] lines = payload.Split('\n');string requestLine = lines[0].Trim();string[] parts = requestLine.Split(' ');if (parts.Length >= 2){string method = parts[0];string url = parts[1];Console.WriteLine($"HTTP请求: {method} {url}");}}}static void AnalyzeHttpsTraffic(TcpPacket tcpPacket){// 获取 IP 包var ipPacket = (IPPacket)tcpPacket.ParentPacket;if (ipPacket != null){// 从 IP 包获取源和目标地址var sourceAddress = ipPacket.SourceAddress;var destinationAddress = ipPacket.DestinationAddress;// 从 TCP 包获取源和目标端口var sourcePort = tcpPacket.SourcePort;var destinationPort = tcpPacket.DestinationPort;Console.WriteLine($"HTTPS连接: {sourceAddress}:{sourcePort} -> {destinationAddress}:{destinationPort}");// 检查 TLS 握手包if (tcpPacket.PayloadData != null && tcpPacket.PayloadData.Length > 0 && tcpPacket.PayloadData[0] == 0x16){Console.WriteLine("检测到TLS握手包");}}else{Console.WriteLine("无法获取 IP 包信息");}}}

6. 实时网络流量统计
using System;using System.Threading;using SharpPcap;class Program{static long packetCount = 0;static long byteCount = 0;static void Main(string[] args){// 获取第一个网络接口using var device = CaptureDeviceList.Instance[6];device.Open(mode: DeviceModes.Promiscuous, read_timeout: 1000);device.OnPacketArrival += (sender, e) =>{Interlocked.Increment(ref packetCount);Interlocked.Add(ref byteCount, e.GetPacket().Data.Length);};// 启动统计线程var statsThread = new Thread(PrintStats);statsThread.Start();device.StartCapture();Console.WriteLine("正在统计网络流量,按任意键停止...");Console.ReadKey();device.StopCapture();statsThread.Join();}static void PrintStats(){long lastPacketCount = 0;long lastByteCount = 0;while (true){Thread.Sleep(1000);long currentPacketCount = Interlocked.Read(ref packetCount);long currentByteCount = Interlocked.Read(ref byteCount);long packetsPerSecond = currentPacketCount - lastPacketCount;long bytesPerSecond = currentByteCount - lastByteCount;Console.WriteLine($"数据包/秒: {packetsPerSecond}, 字节/秒: {bytesPerSecond}");lastPacketCount = currentPacketCount;lastByteCount = currentByteCount;}}}

结论
SharpPcap提供了强大而灵活的数据包捕获和处理功能。通过上述示例,我们展示了如何使用SharpPcap来列出网络设备、捕获实时数据包、读写捕获文件以及收集网络统计信息。这些功能使SharpPcap成为网络分析、安全审计和协议开发等领域的有力工具。
如果你从事上位机,自动化,机器视觉,IOT项目,数字化项目,欢迎加我微信,大家可以一起讨论学习,如果遇到技术问题可以提出来,我会尽量帮你解决问题,但不能保证喔,毕竟个人水平有限!

文章转载自技术老小子,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




