前段时间项目需要处理pcap包,需要读取出来包信息进行处理,网上找了一下资料非常少,最后找到一个开源的包可以满足条件,这里记录一下。
首先是要搜索包文件,然后添加程序包
完成之后就可以使用了。
因为是项目里面使用的,还有一些别的逻辑处理,有些乱就不全粘了,这里单独拉出来一些代码,单独建了一个控制台,代码如下:
1 static void Main(string[] args) 2 { 3 var filePath = @"D:\\email2a.pcap"; 4 List<PacketInfo> list = new List<PacketInfo>(); 5 var device = new SharpPcap.LibPcap.CaptureFileReaderDevice(filePath); 6 device.Open(); 7 while (device.GetNextPacket(out var packet) > 0) 8 { 9 #region 包信息读取,构造List方便处理 10 var packetInfo = new PacketInfo(); 11 if (packet.LinkLayerType != LinkLayers.Ethernet) 12 { 13 continue; 14 } 15 packetInfo.PacketLength = packet.Data.Length; 16 var ethPacket = Packet.ParsePacket(packet.LinkLayerType, packet.Data) as EthernetPacket; 17 var ipPacket = ethPacket.Extract<IPPacket>(); 18 if (ipPacket == null) 19 { 20 continue; 21 } 22 23 packetInfo.DestinationIP = ipPacket.DestinationAddress.ToString(); 24 packetInfo.SourceIP = ipPacket.SourceAddress.ToString(); 25 packetInfo.TransportProtocol = ipPacket.Protocol.ToString(); 26 packetInfo.Time= packet.Timeval.MicroSeconds;//微秒 27 28 if (ethPacket.Type == PacketDotNet.EthernetType.IPv4) 29 { 30 var fragmentFlags = ((PacketDotNet.IPv4Packet)ipPacket).FragmentFlags; 31 packetInfo.IpDf = (ushort)fragmentFlags >> 6 & 0x01;//是否分片 32 packetInfo.IpMf = (ushort)fragmentFlags >> 7 & 0x01;//是否最后一个分片 33 var data = ((PacketDotNet.IPv4Packet)ipPacket).PayloadPacket?.PayloadData; 34 packetInfo.Data = data == null ? "" : BytArrayToHexString(data); 35 packetInfo.IpLen = ((PacketDotNet.IPv4Packet)ipPacket).TotalLength; 36 } 37 else if (ethPacket.Type == PacketDotNet.EthernetType.IPv6) 38 { 39 packetInfo.IpDf = 0; 40 packetInfo.IpMf = 0; 41 var data = ((PacketDotNet.IPv6Packet)ipPacket).PayloadPacket.PayloadData; 42 packetInfo.Data = data == null ? "" : BytArrayToHexString(data); 43 packetInfo.IpLen = ((PacketDotNet.IPv6Packet)ipPacket).TotalLength; 44 } 45 packetInfo.IpTtl = ipPacket.HopLimit; 46 if (packetInfo.TransportProtocol == "Tcp") 47 { 48 packetInfo.SourcePort = ((PacketDotNet.TcpPacket)ipPacket.PayloadPacket).SourcePort; 49 packetInfo.DestinationPort = ((PacketDotNet.TcpPacket)ipPacket.PayloadPacket).DestinationPort; 50 packetInfo.PSH = ((PacketDotNet.TcpPacket)ipPacket.PayloadPacket).Push ? 1 : 0; 51 packetInfo.URG = ((PacketDotNet.TcpPacket)ipPacket.PayloadPacket).Urgent ? 1 : 0; 52 packetInfo.ThWin = ((PacketDotNet.TcpPacket)ipPacket.PayloadPacket).WindowSize; 53 packetInfo.ThUrp = ((PacketDotNet.TcpPacket)ipPacket.PayloadPacket).UrgentPointer; 54 packetInfo.ThSeq = ((PacketDotNet.TcpPacket)ipPacket.PayloadPacket).SequenceNumber; 55 } 56 else if (packetInfo.TransportProtocol == "Udp") 57 { 58 packetInfo.SourcePort = ((PacketDotNet.UdpPacket)ipPacket.PayloadPacket).SourcePort; 59 packetInfo.DestinationPort = ((PacketDotNet.UdpPacket)ipPacket.PayloadPacket).DestinationPort; 60 packetInfo.PSH = 0; 61 packetInfo.URG = 0; 62 packetInfo.ThWin = 0; 63 packetInfo.ThUrp = 0; 64 packetInfo.ThSeq = 0; 65 } 66 else 67 { 68 if (ipPacket.Protocol == PacketDotNet.ProtocolType.IPSecEncapsulatingSecurityPayload) 69 { 70 var data = ipPacket.PayloadData; 71 var length = data.Length; 72 if (length > 8) 73 { 74 var espData = new byte[length - 8]; 75 Array.Copy(data, 8, espData, 0, espData.Length); 76 packetInfo.Data = data == null ? "" : BytArrayToHexString(espData); 77 } 78 } 79 packetInfo.TransportProtocol = "ESP";//这里将esp统一处理非tcp和udp的协议 80 } 81 list.Add(packetInfo); 82 #endregion 83 } 84 Console.WriteLine("解析完成!"); 85 }
PacketInfo类
1 public class PacketInfo 2 { 3 /// <summary> 4 /// 代表发出的分组 5 /// </summary> 6 public int DirectionForward { get; set; } 7 8 /// <summary> 9 /// 代表接收的分组 10 /// </summary> 11 public int DirectionBackward { get; set; } 12 13 /// <summary> 14 /// 距离流开始的时间 15 /// </summary> 16 public double Time { get; set; } 17 18 /// <summary> 19 /// 分组IP层以上内容长度(包括IP层) 20 /// </summary> 21 public int IpLen { get; set; } 22 23 /// <summary> 24 /// 分组是否分片 25 /// </summary> 26 public int IpDf { get; set; } 27 28 /// <summary> 29 /// 分组是否是最后一个分片 30 /// </summary> 31 public int IpMf { get; set; } 32 33 /// <summary> 34 /// 跳数,表示分组最多能够走多少个路由 35 /// </summary> 36 public int IpTtl { get; set; } 37 38 /// <summary> 39 /// 代表tcp传输层序列号 40 /// </summary> 41 public uint ThSeq { get; set; } 42 43 /// <summary> 44 /// tcp_flag的一种,表示紧急指针有效 45 /// </summary> 46 public int URG { get; set; } 47 48 /// <summary> 49 /// tcp_flag的一种,表示有数据进行传输 50 /// </summary> 51 public int PSH { get; set; } 52 53 /// <summary> 54 /// 代表传输层窗口大小 55 /// </summary> 56 public int ThWin { get; set; } 57 58 /// <summary> 59 /// 代表紧急指针 60 /// </summary> 61 public int ThUrp { get; set; } 62 63 public string Data { get; set; } 64 65 public string SourceIP { get; set; } 66 67 public int SourcePort { get; set; } 68 69 public string DestinationIP { get; set; } 70 71 public int DestinationPort { get; set; } 72 73 public string TransportProtocol { get; set; } 74 75 public int PacketLength { get; set; } 76 77 }
转换为16进制方法
1 public static string BytArrayToHexString(byte[] data) 2 { 3 StringBuilder sb = new StringBuilder(data.Length * 3); 4 foreach (var item in data) 5 { 6 sb.Append(Convert.ToString(item, 16).PadLeft(2, '0')); 7 } 8 return sb.ToString().ToUpper(); 9 }