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),布布扣,bubuko.com
SharpPcap抓包调试(visual studio 2010、winpcap 4.1.2、SharpPcap 3.1.0)