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();
        }

  

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM