
使用sharppcap抓数据包.docx
9页使用 sharppcap抓数据包首先用到 PacketDotNet,SharpPcap 这两个 DLL,工具 Ethereal 可以分析包内容class Program{static bool showDetails = false; //查看详情的参数private static bool BackgroundThreadStop = false; //线程停止标识private static object QueueLock = new object(); //线程锁变量private static List PacketQueue = new List(); //待处理数据包队列static void Main(string[] args){//显示 SharpPcap版本string ver = SharpPcap.Version.VersionString;Console.WriteLine("SharpPcap {0}", ver);//获取网络设备var devices = LivePcapDeviceList.Instance;if (devices.Count /// 抓包方法/// static void device_OnPacketArrival(object sender, CaptureEventArgs e){PcapPorcessContext(e.Packet);}private static void PcapPorcessContext(PacketDotNet.RawPacket pPacket){var time = pPacket.Timeval.Date;var len = pPacket.Data.Length;var layer = pPacket.LinkLayerType;Console.WriteLine("{0}:{1}:{2},{3} 长度={4} 第几层={5}",time.Hour, time.Minute, time.Second, time.Millisecond, len, layer);Console.WriteLine("content is {0}", Encoding.ASCII.GetString(pPacket.Data));var packet = PacketDotNet.Packet.ParsePacket(pPacket); //Raw基础包对象if (layer == PacketDotNet.LinkLayers.Ethernet) //以太网包{var ethernetPacket = (PacketDotNet.EthernetPacket)packet;System.Net.NetworkInformation.PhysicalAddress srcMac = ethernetPacket.SourceHwAddress;System.Net.NetworkInformation.PhysicalAddress destMac = ethernetPacket.DestinationHwAddress;Console.WriteLine("MAC:{0} -> {1}", srcMac, destMac);if (showDetails)Console.WriteLine("以太网包: " + ethernetPacket.ToColoredString(false));}var ipPacket = PacketDotNet.IpPacket.GetEncapsulated(packet); //ip包 if (ipPacket != null){System.Net.IPAddress srcIp = ipPacket.SourceAddress;System.Net.IPAddress destIp = ipPacket.DestinationAddress;Console.WriteLine("IP: {0} -> {1}", srcIp, destIp);if (showDetails) Console.WriteLine("IP packet: " + ipPacket.ToColoredString(false));var tcpPacket = PacketDotNet.TcpPacket.GetEncapsulated(packet); //TCP包if (tcpPacket != null){int srcPort = tcpPacket.SourcePort;int destPort = tcpPacket.DestinationPort;Console.WriteLine("TCP Port: {0} -> {1}", srcPort, destPort);if (showDetails) Console.WriteLine("TCP packet: " + tcpPacket.ToColoredString(false));}var udpPacket = PacketDotNet.UdpPacket.GetEncapsulated(packet); //UDP包if (udpPacket != null){int srcPort = udpPacket.SourcePort;int destPort = udpPacket.DestinationPort;Console.WriteLine("UDP Port: {0} -> {1}", srcPort, destPort);if (showDetails) Console.WriteLine("UDP packet: " + udpPacket.ToColoredString(false));}}}static ulong oldSec = 0;static ulong oldUsec = 0;/// /// 抓包统计方法/// static void device_OnPcapStatistics(object sender, StatisticsModeEventArgs e){// 计算统计心跳间隔ulong delay = (e.Statistics.Timeval.Seconds - oldSec) * 1000000 - oldUsec + e.Statistics.Timeval.MicroSeconds;// 获取 Bits per secondulong bps = ((ulong)e.Statistics.RecievedBytes * 8 * 1000000) / delay;/* ^ ^| || | | |converts bytes in bits -- ||delay is expressed in microseconds --*/// 获取 Packets per secondulong pps = ((ulong)e.Statistics.RecievedPackets * 1000000) / delay;// 将时间戳装换为易读格式var ts = e.Statistics.Timeval.Date.ToLongTimeString();// 输出统计结果Console.WriteLine("{0}: bps={1}, pps={2}", ts, bps, pps);//记录本次统计时间戳,以用于下次统计计算心跳间隔oldSec = e.Statistics.Timeval.Seconds;oldUsec = e.Statistics.Timeval.MicroSeconds;}/// /// /// private static DateTime LastStatisticsOutput = DateTime.Now;private static TimeSpan LastStatisticsInterval = new TimeSpan(0, 0, 2);static void device_OnThreadPacketArrival(object sender, CaptureEventArgs e){//输出设备通讯统计信息var Now = DateTime.Now; var interval = Now - LastStatisticsOutput;if (interval > LastStatisticsInterval){Console.WriteLine("Device Statistics: " + ((LivePcapDevice)e.Device).Statistics());LastStatisticsOutput = Now;}lock (QueueLock){PacketQueue.Add(e.Packet); //将捕获到的数据包加入处理队列}}/// /// 多线程处理数据包队列/// private static void BackgroundThread(){while (!BackgroundThreadStop){bool shouldSleep = true;lock (QueueLock){if (PacketQueue.Count != 0){shouldSleep = false;}}if (shouldSleep){System.Threading.Thread.Sleep(250);}else //处理队列{List ourQueue; //本线程待处理队列lock (QueueLock){ourQueue = PacketQueue;PacketQueue = new List();}Console.WriteLine("BackgroundThread: Local Queue Count is {0}", ourQueue.Count);foreach (var packet in ourQueue){PcapPorcessContext(packet);}}}}/// /// 生成一个大小为 200的随机数据包/// private static byte[] GetRandomPacket(){byte[] packet = new byte[200];Random rand = new Random();rand.NextBytes(packet);return packet;}}。
