SharpPcap抓包调试(visual studio 2010、winpcap 4.1.2、SharpPcap 3.1.0)

SharpPcap抓包调试(visual studio 2010、winpcap 4.1.2、SharpPcap 
3.1.0)
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using SharpPcap;
  6 
  7 namespace TestConsole
  8 {
  9     class Program
 10     {
 11         static void Main(string[] args)
 12         {
 13             //显示SharpPcap版本
 14             string ver = SharpPcap.Version.VersionString;
 15             Console.WriteLine("SharpPcap {0}", ver);
 16 
 17             //获取网络设备
 18             var devices = LivePcapDeviceList.Instance;
 19             if (devices.Count < 1)
 20             {
 21                 Console.WriteLine("找不到网络设备");
 22                 return;
 23             }
 24             Console.WriteLine();
 25             Console.WriteLine("以下是目前本计算机上的活动网络设备:");
 26             Console.WriteLine("----------------------------------------------------");
 27             Console.WriteLine();
 28             int i = 0;
 29             foreach (LivePcapDevice dev in devices)
 30             {
 31                 Console.WriteLine("{0}) {1} {2}", i, dev.Name, dev.Description);
 32                 i++;
 33             }
 34 
 35             //选择要监听的网络设备
 36             Console.WriteLine();
 37             Console.Write("-- 请选择一个需要监听的网络设备: ");
 38             i = int.Parse(Console.ReadLine());
 39             LivePcapDevice device = devices[i];
 40 
 41             Console.Write("-- 请选择操作:监听通讯[C/c],多线程监听通讯[T/t],监听统计[F/f],发送随机数据包[S/s]? ");
 42             string resp = Console.ReadLine().ToUpper();
 43 
 44             while (!(resp.StartsWith("C") || resp.StartsWith("F") || resp.StartsWith("T") || resp.StartsWith("S")))
 45             {
 46                 resp = Console.ReadLine().ToUpper();
 47             }
 48 
 49             try
 50             {
 51                 if (resp.StartsWith("C") || resp.StartsWith("F") || resp.StartsWith("T"))
 52                 {
 53                     //监听过滤条件
 54                     string filter = "ip and tcp";
 55 
 56                     //连接设备
 57                     System.Threading.Thread backgroundThread = null;
 58                     int readTimeoutMilliseconds = 1000;
 59                     if (resp.StartsWith("F"))
 60                     {
 61                         device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
 62                         device.SetFilter(filter);
 63                         device.Mode = CaptureMode.Statistics; //抓包统计
 64                         device.OnPcapStatistics += new StatisticsModeEventHandler(device_OnPcapStatistics); //抓包统计回调事件
 65                     }
 66                     else if (resp.StartsWith("C"))
 67                     {
 68                         device.Open(DeviceMode.Promiscuous, readTimeoutMilliseconds);
 69                         device.SetFilter(filter);
 70                         device.Mode = CaptureMode.Packets; //抓数据包
 71                         showDetails = resp.EndsWith("-A"); //当抓数据包时,检查是否要查看详情
 72                         device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival); //抓数据包回调事件
 73                     }
 74                     else
 75                     {
 76                         backgroundThread = new System.Threading.Thread(BackgroundThread);
 77                         backgroundThread.Start();
 78                         device.Open();
 79                         device.SetFilter(filter);
 80                         device.Mode = CaptureMode.Packets; //抓数据包
 81                         showDetails = resp.EndsWith("-A"); //当抓数据包时,检查是否要查看详情
 82                         device.OnPacketArrival += new PacketArrivalEventHandler(device_OnThreadPacketArrival); //抓数据包回调事件
 83                     }      
 84                     
 85                     Console.WriteLine();
 86                     Console.WriteLine("-- 当前TCPdump过滤条件: /{0}/", filter);
 87                     Console.WriteLine("-- 正在监听设备 {0}, 按 ‘回车‘ 键以停止监听...", device.Description);
 88 
 89                     //开始监听
 90                     device.StartCapture();
 91 
 92                     //停止监听
 93                     Console.ReadLine();
 94                     device.StopCapture();
 95                     Console.WriteLine("-- 停止监听.");
 96 
 97                     if (backgroundThread != null)
 98                     {
 99                         BackgroundThreadStop = true;
100                         backgroundThread.Join();
101                     }
102                 }
103                 else if (resp.StartsWith("S"))
104                 {
105                     //连接设备
106                     device.Open();
107 
108                     //生成随机数据包
109                     byte[] bytes = GetRandomPacket();
110 
111                     try
112                     {
113                         //发送数据
114 
115                         device.SendPacket(bytes);
116                         SendQueue squeue = new SendQueue(2000);
117                         Console.WriteLine("-- 单个数据包发送成功.");
118 
119                         for (int j = 0; j < 10; j++)
120                         {
121                             if (!squeue.Add(bytes))
122                             {
123                                 Console.WriteLine("-- 警告: 队列大小不足以存放所有数据包,将只发送部分数据包.");
124                                 break;
125                             }
126                         }
127                         device.SendQueue(squeue, SendQueueTransmitModes.Synchronized);
128                         Console.WriteLine("-- 数据包队列发送完毕.");
129                     }
130                     catch (Exception e)
131                     {
132                         Console.WriteLine("-- " + e.Message);
133                     }
134                 }
135             }
136             catch (Exception e)
137             {
138                 Console.WriteLine("-- " + e.Message);
139             }
140             finally
141             {
142                 if (device.Opened)
143                 {
144                     //断开设备连接
145                     Console.WriteLine(device.Statistics().ToString());
146                     device.Close();
147                     Console.WriteLine("-- 断开设备连接.");
148                     Console.Write("按 ‘回车‘ 键以退出...");
149                     Console.Read();
150                 }
151             }
152         }
153 
154         static bool showDetails = false; //查看详情的参数
155         /// <summary>
156         /// 抓包方法
157         /// </summary>
158         private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
159         {
160             PcapPorcessContext(e.Packet);
161         }
162 
163         private static void PcapPorcessContext(PacketDotNet.RawPacket pPacket)
164         {
165             var time = pPacket.Timeval.Date;
166             var len = pPacket.Data.Length;
167             var layer = pPacket.LinkLayerType;
168 
169             Console.WriteLine("{0}:{1}:{2},{3} Len={4} Layer={5}",
170                     time.Hour, time.Minute, time.Second, time.Millisecond, len, layer);
171 
172             var packet = PacketDotNet.Packet.ParsePacket(pPacket); //Raw基础包对象
173 
174             if (layer == PacketDotNet.LinkLayers.Ethernet) //以太网包
175             {
176                 var ethernetPacket = (PacketDotNet.EthernetPacket)packet;
177                 System.Net.NetworkInformation.PhysicalAddress srcMac = ethernetPacket.SourceHwAddress;
178                 System.Net.NetworkInformation.PhysicalAddress destMac = ethernetPacket.DestinationHwAddress;
179 
180                 Console.WriteLine("MAC:{0} -> {1}", srcMac, destMac);
181                 if (showDetails) Console.WriteLine("Ethernet packet: " + ethernetPacket.ToColoredString(false));
182             }
183             var ipPacket = PacketDotNet.IpPacket.GetEncapsulated(packet);  //IP包
184             if (ipPacket != null)
185             {
186                 System.Net.IPAddress srcIp = ipPacket.SourceAddress;
187                 System.Net.IPAddress destIp = ipPacket.DestinationAddress;
188 
189                 Console.WriteLine("IP: {0} -> {1}", srcIp, destIp);
190                 if (showDetails) Console.WriteLine("IP packet: " + ipPacket.ToColoredString(false));
191 
192                 var tcpPacket = PacketDotNet.TcpPacket.GetEncapsulated(packet); //TCP包
193                 if (tcpPacket != null)
194                 {
195                     int srcPort = tcpPacket.SourcePort;
196                     int destPort = tcpPacket.DestinationPort;
197 
198                     Console.WriteLine("TCP Port: {0} -> {1}", srcPort, destPort);
199                     if (showDetails) Console.WriteLine("TCP packet: " + tcpPacket.ToColoredString(false));
200                 }
201 
202                 var udpPacket = PacketDotNet.UdpPacket.GetEncapsulated(packet); //UDP包
203                 if (udpPacket != null)
204                 {
205                     int srcPort = udpPacket.SourcePort;
206                     int destPort = udpPacket.DestinationPort;
207 
208                     Console.WriteLine("UDP Port: {0} -> {1}", srcPort, destPort);
209                     if (showDetails) Console.WriteLine("UDP packet: " + udpPacket.ToColoredString(false));
210                 }
211             }
212         }
213 
214         static ulong oldSec = 0;
215         static ulong oldUsec = 0;
216         /// <summary>
217         /// 抓包统计方法
218         /// </summary>
219         private static void device_OnPcapStatistics(object sender, StatisticsModeEventArgs e)
220         {
221             // 计算统计心跳间隔
222             ulong delay = (e.Statistics.Timeval.Seconds - oldSec) * 1000000 - oldUsec + e.Statistics.Timeval.MicroSeconds;
223 
224             // 获取 Bits per second
225             ulong bps = ((ulong)e.Statistics.RecievedBytes * 8 * 1000000) / delay;
226             /*                                       ^       ^
227                                                      |       |
228                                                      |       | 
229                                                      |       |
230                             converts bytes in bits --        |
231                                                              |
232                         delay is expressed in microseconds --
233             */
234 
235             // 获取 Packets per second
236             ulong pps = ((ulong)e.Statistics.RecievedPackets * 1000000) / delay;
237 
238             // 将时间戳装换为易读格式
239             var ts = e.Statistics.Timeval.Date.ToLongTimeString();
240 
241             // 输出统计结果
242             Console.WriteLine("{0}: bps={1}, pps={2}", ts, bps, pps);
243 
244             //记录本次统计时间戳,以用于下次统计计算心跳间隔
245             oldSec = e.Statistics.Timeval.Seconds;
246             oldUsec = e.Statistics.Timeval.MicroSeconds;
247         }
248 
249         /// <summary>
250         /// 生成一个大小为200的随机数据包
251         /// </summary>
252         private static byte[] GetRandomPacket()
253         {
254             byte[] packet = new byte[200];
255             Random rand = new Random();
256             rand.NextBytes(packet);
257             return packet;
258         }
259 
260         /// <summary>
261         /// 生成一个大小为98的数据包
262         /// </summary>
263         private static byte[] GetPacket()
264         {
265             byte[] packet = new byte[]
266             {
267                 0x00,0x02,0x65,0x11,0xa6,0x05,                     //srcMac
268                 0x00,0x1b,0x38,0xa5,0xc2,0x40,                     //destMac
269                 0x08,0x00,                                         //Type Ip
270                 0x45,                                              //Version 4
271                 0x00,                                              //Differentiated Services Field 分隔符
272                 0x00,0x54,                                         //Total Length 84
273                 0x43,0x08,                                         //Identification 校验位
274                 0x40,0x00,                                         //Fragment offset 片偏移
275                 0x80,                                              //Time to live 生存时间
276                 0x06,                                              //Protocol TCP
277                 0x40,0x00,                                         //Header checksum 报头校验和
278                 0xc0,0xa8,0x00,0x71,                               //srcIP
279                 0xc0,0xa8,0x00,0x6a,                               //destIP
280                 0x26,0x8e,                                         //srcPort
281                 0x04,0x04,                                         //destPort
282                 0x5b,0x0c,0x5e,0xc7,                               //Sequence number 序号
283                 0xca,0xf9,0x1b,0xb1,                               //Acknowledgement number 应答号
284                 0x80,                                              //Header Length 32
285                 0x18,                                              //Flags [PSH,ACK]
286                 0x41,0x10,                                         //Window size
287                 0x82,0x72,                                         //Checksum 校验和
288                 0x01,                                              //Options NOP
289                 0x01,                                              //Options NOP
290                 0x08,0x0a,0x00,0x00,0xac,0x4c,0x00,0x41,0x50,0xaa, //Options Timestamps
291                 0x21,                                              //Data Start 这之后是我这个项目中的服务器和终端通讯的特有的附加数据
292                 0x0a,                                              //Command
293                 0x00,0x00,                                         //CID
294                 0x01,0x00,0x00,0x00,                               //TID
295                 0x00,0x00,0x00,0x00,                               //Param1
296                 0x00,0x00,0x00,0x00,                               //Param2
297                 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,           //Param3
298                 0x30,0x30,0x30,0x30,                               //ErrorCode
299                 0x00,0x00,0xec,0x00                                //ExtraData
300             };
301             return packet;
302         }
303 
304         private static DateTime LastStatisticsOutput = DateTime.Now;
305         private static TimeSpan LastStatisticsInterval = new TimeSpan(0, 0, 2);
306         private static void device_OnThreadPacketArrival(object sender, CaptureEventArgs e)
307         {
308             //输出设备通讯统计信息
309             var Now = DateTime.Now;
310             var interval = Now - LastStatisticsOutput;
311             if (interval > LastStatisticsInterval)
312             {
313                 Console.WriteLine("Device Statistics: " + ((LivePcapDevice)e.Device).Statistics());
314                 LastStatisticsOutput = Now;
315             }
316 
317             lock (QueueLock)
318             {
319                 PacketQueue.Add(e.Packet); //将捕获到的数据包加入处理队列
320             }
321         }
322 
323         /// <summary>
324         /// 多线程处理数据包队列
325         /// </summary>
326         private static void BackgroundThread()
327         {
328             while (!BackgroundThreadStop)
329             {
330                 bool shouldSleep = true;
331 
332                 lock (QueueLock)
333                 {
334                     if (PacketQueue.Count != 0)
335                     {
336                         shouldSleep = false;
337                     }
338                 }
339 
340                 if (shouldSleep)
341                 {
342                     System.Threading.Thread.Sleep(250);
343                 }
344                 else //处理队列
345                 {
346                     List<PacketDotNet.RawPacket> ourQueue; //本线程待处理队列
347                     lock (QueueLock)
348                     {
349                         ourQueue = PacketQueue;
350                         PacketQueue = new List<PacketDotNet.RawPacket>();
351                     }
352 
353                     Console.WriteLine("BackgroundThread: Local Queue Count is {0}", ourQueue.Count);
354 
355                     foreach (var packet in ourQueue)
356                     {
357                         PcapPorcessContext(packet);
358                     }
359                 }
360             }
361         }
362         private static bool BackgroundThreadStop = false; //线程停止标识
363         private static object QueueLock = new object(); //线程锁变量
364         private static List<PacketDotNet.RawPacket> PacketQueue = new List<PacketDotNet.RawPacket>(); //待处理数据包队列
365     }
366 }
SharpPcap抓包调试(visual studio 2010、winpcap 4.1.2、SharpPcap 
3.1.0)

 

SharpPcap抓包调试(visual studio 2010、winpcap 4.1.2、SharpPcap 3.1.0),布布扣,bubuko.com

SharpPcap抓包调试(visual studio 2010、winpcap 4.1.2、SharpPcap 3.1.0)

上一篇:Mycat(配置篇)


下一篇:递归练习:计算最大公约数和最小公倍数