zoukankan      html  css  js  c++  java
  • C# 使用SharpPcap读写Pcap包

    问题描述:

            最近公司新开发一个项目,需要读取pcap包信息,然后去分析。这个也是走了不少弯路,以前也没处理过这么底层的东西,网上能找到的例子也有限,最后用了SharpPcap这个工具,基本可以满足需要,这个工具读取的信息很全,我就不粘贴那么细了,具体的取值类似。

    这里用控制台写两个例子做个示范:

    1、pacp包信息读取,如果需要更多的值,建议可以进去断点看看,这里只是写个示范。

           public static void Main(string[] args)
            {
                Console.WriteLine("Start!");
                string filePath = @"D:123.pcap";
                var device = new SharpPcap.LibPcap.CaptureFileReaderDevice(filePath);
                device.Open();
                while (device.GetNextPacket(out var packet) > 0)
                {
                    var sourceAddr = string.Empty;
                    var destAddr = string.Empty;
                    var protocol = string.Empty;
                    int sourcePort = 0;
                    int destPort = 0;
                    int ipDf = 0;//是否分片
                    int ipMf = 0;//是否最后一个分片
                    long totalLength = 0;//总长度
                    string data16 = string.Empty;//字节转为16进制字符串
                    if (packet.LinkLayerType != LinkLayers.Ethernet)
                    {
                        continue;
                    }
                    var packetLength = packet.Data.Length;
                    var ethPacket = Packet.ParsePacket(packet.LinkLayerType, packet.Data) as EthernetPacket;
                    var ipPacket = ethPacket.Extract<IPPacket>();
                    if (ipPacket == null)
                    {
                        continue;
                    }
                    destAddr = ipPacket.DestinationAddress.ToString();
                    sourceAddr = ipPacket.SourceAddress.ToString();
                    protocol = ipPacket.Protocol.ToString();
                    if (ethPacket.Type == PacketDotNet.EthernetType.IPv4)
                    {
                        var fragmentFlags = ((PacketDotNet.IPv4Packet)ipPacket).FragmentFlags;
                        ipDf = (ushort)fragmentFlags >> 6 & 0x01;
                        ipMf = (ushort)fragmentFlags >> 7 & 0x01;
                        var data = ((PacketDotNet.IPv4Packet)ipPacket).PayloadPacket?.PayloadData;
                        data16 = BytArrayToHexString(data);
                        totalLength = ((PacketDotNet.IPv4Packet)ipPacket).TotalLength;
                    }
                    else if (ethPacket.Type == PacketDotNet.EthernetType.IPv6)
                    {
                        var data = ((PacketDotNet.IPv6Packet)ipPacket).PayloadPacket.PayloadData;
                        data16 = BytArrayToHexString(data);
                        totalLength = ((PacketDotNet.IPv6Packet)ipPacket).TotalLength;
                    }
                    if (protocol == "Tcp")
                    {
                        sourcePort = ((PacketDotNet.TcpPacket)ipPacket.PayloadPacket).SourcePort;
                        destPort = ((PacketDotNet.TcpPacket)ipPacket.PayloadPacket).DestinationPort;
                    }
                    else if (protocol == "Udp")
                    {
                        sourcePort = ((PacketDotNet.UdpPacket)ipPacket.PayloadPacket).SourcePort;
                        destPort = ((PacketDotNet.UdpPacket)ipPacket.PayloadPacket).DestinationPort;
                    }
                    Console.WriteLine($"sourceAddr:{sourceAddr}, sourcePort:{sourcePort}, destAddr:{destAddr}, destPort:{destPort},protocol:{protocol}");
                }
                device.Close();
                Console.WriteLine("End!");
            }
    
            public static string BytArrayToHexString(byte[] data)//16进制转换
            {
                StringBuilder sb = new StringBuilder(data.Length * 3);
                foreach (var item in data)
                {
                    sb.Append(Convert.ToString(item, 16).PadLeft(2, '0'));
                }
                return sb.ToString().ToUpper();
            }
    

    2、从pcap包中筛选信息,重新写数据包,这里实例演示写TCP的包,其余类型的一律过滤掉。(output.pcap找一个正常包就行,写的时候会覆盖的)

            public static void Main(string[] args)
            {
                Console.WriteLine("Start");
                var device = new SharpPcap.LibPcap.CaptureFileReaderDevice(@"D:123.pcap");
                var deviceOutput = new SharpPcap.LibPcap.CaptureFileWriterDevice(@"D:output.pcap");
                device.Open();
                deviceOutput.Open();
                while (device.GetNextPacket(out var packet) > 0)
                {
                    if (packet.LinkLayerType != LinkLayers.Ethernet)
                    {
                        continue;
                    }
                    var ethPacket = Packet.ParsePacket(packet.LinkLayerType, packet.Data) as EthernetPacket;
                    var ipPacket = ethPacket.Extract<IPPacket>();
                    if (ipPacket == null)
                    {
                        continue;
                    }
                    if (ipPacket.Protocol == PacketDotNet.ProtocolType.Tcp)
                    {
                        deviceOutput.Write(packet);
                    }
                    Console.WriteLine($"SrcMac:{ethPacket.SourceHardwareAddress}, DstMac:{ethPacket.DestinationHardwareAddress}, SrcIP:{ipPacket.SourceAddress}, DstIP:{ipPacket.DestinationAddress}");
    
                    //再往上各层的分析以此类推
                }
                device.Close();
                deviceOutput.Close();
                Console.WriteLine("End!");
                Console.ReadLine();
            }
    

      

      

  • 相关阅读:
    Pro mvvm读书笔记mvvm中的VM
    pro mvvm 读书笔记
    WPF/Silverlight中的RichTextBox总结
    wpf treeview中的两个事件
    CLR执行模型与常见的几个概念
    IntelliJ IDEA 2017版 使用笔记(十二) 其他操作:IDEA 快捷键
    IntelliJ IDEA 2017版 使用笔记(十一) Debug操作:IDEA 快捷键
    IntelliJ IDEA 2017版 编译器使用学习笔记(十) (图文详尽版);IDE快捷键使用;IDE关联一切
    IntelliJ IDEA 2017版 编译器使用学习笔记(九)(图文详尽版);IDE使用的有趣的插件;IDE代码统计器;Mybatis插件
    IntelliJ IDEA 2017版 编译器使用学习笔记(八) (图文详尽版);IDE快捷键使用;IDE代码重构(寻找修改痕迹)
  • 原文地址:https://www.cnblogs.com/zhangjd/p/13305918.html
Copyright © 2011-2022 走看看