C#使用SharpPcap读写Pcap包
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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();
}。