暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

C# 数据包捕获 SharpPcap库应用指南

技术老小子 2024-10-02
46

SharpPcap是一个功能强大的.NET库,用于跨平台(Windows、Mac、Linux)的数据包捕获。本文将介绍SharpPcap的主要特性,并提供几个详细的应用示例。

主要特性

  1. 跨平台支持:

    • Linux: 支持libpcap

    • Windows: 支持Npcap和WinDivert

    • 所有平台: 支持实时设备列表、统计信息、从实时设备和离线设备读取数据包

  2. 数据包处理:

    • 支持Berkeley数据包过滤器

    • 可以将数据包转储到Pcap文件

    • 支持Pcap和pcap-ng格式(使用libpcap >=1.1.0或npcap时)

  3. 性能优化:

    • 使用ReadOnlySpan<>避免内存分配和复制

    • 提供辅助方法将捕获的数据包转换为对象实例

  4. 其他特性:

    • 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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论