C#版的抓包软件

 

[创建时间:2015-09-10 22:37:04]

NetAnalyzer下载地址

不好意思啊,NetAnalyzer停更有点长了,今天继续填坑^&^

NetAnalyzer实现结构

在上一篇中介绍一点VC++开发环境的配置,与基本的运行方式。因为NetAnalyzer使用的C#作为开发语言,所以在此主要介绍一些在C#环境下的开发环境的配置,与一些基本开发情况,力求在完成本篇后后,读者可以制作一个简单的抓包程序。

在开始编程前先要介绍连个.Net类库SharpPcap.dll与PacketDotNet.dll。在2004年Tamir Gal为了完成他的毕业设计,其中有一些内容需要使用Winpcap来实现网络数据分析,但希望可以使用简单易用的C#开发语言。于是建立了SharpPcap项目,Tamir Gal为了节省时间,并没用将网络数据采集部分与分析部分分开,甚至有些代码混杂在UI代码中。而且在实现了很少的WinPcapAPI接口,并没用提供相关的开发文档。

因为这样,Tamir决定重新设计SharPcap,并推出了1.x一些列的版本,最终在2007年完成了SharpPcap1.6.2版本。

在2008年11月Chris Morgan接替了Tamir的工作,重新设计了SharpPcap的API,开始支持Linux 和MAC(在Linux 与MAC平台的相关技术请参见Mono开发平台)。之后将数据采集于协议分析分别封装在不同的程序集类库中即形成了SharpPcap于Packet.Net。

下载地址:http://sourceforge.net/projects/sharppcap/ 在GNU协议下的开源代码。

(1)     SharpPcap.dll

SharpPcap中封装了Winpcap提供的大部分API函数,在该类库中,我们可以获取主机网卡,及其信息。并定义了对网卡的各种操作方法,如打开网卡,开始抓包,停止抓包等,再抓包中提供了,同步方式与异步方式,方便进行不同的环境,对于更加详细的介绍,将会在下一章提到。

(2)     Packet.Net

在程序集中的名称为PacketDotNet,该类库负责对捕获的数据进行分析解析,目前提供可以分析的协议:

Ethernet、SLL (Linux Cooked-Mode Capture) 、ARP、IPv4 、IPv6 、TCP 、UDP 、ICMPv4、ICMPv6 、IGMPv2 、PPPoE 、PTP 、LLDP 、Wake-on-LAN(WOL)

在NetAnalyzer此基础上,在类库中增加了PPP、LCP、CiscoHDLC等协议。

为了可以分析应用层协议,在NetAnalyzer设计了ApplicationProtocol类库,目前提供HTTP、FTP、DNS、SMTP、POP3、SSDP协议的解析,本节中不会对应用层协议进行分析。

在以下的内容中,我们将分七个部分,来完成一个简单的抓包程序。同上面一样,所有的程序都在Visual Studio2013中完成,只是在这里我们首先要得到:

SharpPcap.dll版本4.0.0

PacketDotNet.dl版本0.11.0

可以通过上面的网址获取。

1 获取网络适配器(网卡)

首先新建工程,开发语言选择C#,类型选择Windows窗体应用程序,命名为MySniffer,图形界面如图1所示。

图1 建立MySniffer工程

点击确定,在解决方案资源管理器中右击引用添加引用, 此时打开添加应用对话框,选择浏览选项卡,并找到SharpPcap与PacketDotNet类库将其添加至工程中。如图2所示,

图2从引用中右击添加引用

在添加完成之后,项目应用中应该可以看到这两个类库的的引用文件。

首先我们来获取需要监听的网卡,在窗体中添加如下代码:

  1. 1 private void loadDevice()// 获取网卡方法
  2. 2 {
  3. 3 try
  4. 4 {
  5. 5 foreach (var i in CaptureDeviceList.Instance)
  6. 6 {
  7. 7 comDeviceList.Items.Add(i.Description); //在combox中添加
  8. 8 }
  9. 9 if (comDeviceList.Items.Count > 0)
  10. 10 {
  11. 11 comDeviceList.SelectedIndex = 0;//自动选中第一个
  12. 12 }
  13. 13 }
  14. 14 catch (Exception ex)
  15. 15 {
  16. 16 MessageBox.Show(ex.Message);
  17. 17 return;
  18. 18 }
  19. 19 }

我们通过调用SharpPcap.CaptureDeviceList.Instance 单例,获取一个包含所用网卡的列表CaptureDeviceList,然后把以此把网卡的描述信息添加到顶部工具栏comDeviceList 中

在代码中我们加一个全局变量device用来指示当前控制的网卡,

  1. 1 ICaptureDevice device;// 定义设备

所以当我们每次去选择不同的网卡时调用下面的方法

  1. 1 //选择网卡
  2. 2 private void comDeviceList_SelectedIndexChanged(object sender, EventArgs e)
  3. 3 {
  4. 4 device = CaptureDeviceList.Instance[comDeviceList.SelectedIndex];
  5. 5 }

完成运行如图

图3获取的网卡以及其信息

接下来我们直接来点精彩的,加入如下代码:

  1. 1 List<RawCapture> packetList = new List<RawCapture>();//捕获的数据列表
  2. 2 List<RawCapture> bufferList;//缓存列表
  3. 3 Thread AnalyzerThread;//分析数据的线程
  4. 4 object threadLock = new object();//线程锁定
  5. 5 bool isStartAnalyzer;//用于表示是否启动分析线程的标志
  6. 6 DeviceMode devMode = DeviceMode.Promiscuous;//数据采集模式
  7. 7 int readTimeOut = 1000;
  8. 8 delegate void DataGridRowsShowHandler(RawCapture packet);
  9. 9
  10. 10
  11. 11 /// <summary>
  12. 12 /// 启动网卡
  13. 13 /// </summary>
  14. 14 private void Start()
  15. 15 {
  16. 16 if (device == null || device.Started)
  17. 17 return;
  18. 18 bufferList = new List<RawCapture>();
  19. 19 Clear();//清理原有的数据
  20. 20 isStartAnalyzer = true;
  21. 21 StartAnalyzer();//启动分析线程
  22. 22 try
  23. 23 {
  24. 24 device.OnPacketArrival += new PacketArrivalEventHandler(device_OnPacketArrival);
  25. 25 //默认使用混杂模式,超时 1000
  26. 26 device.Open(devMode, readTimeOut);
  27. 27 device.Filter = comFilter.Text;
  28. 28 device.StartCapture();
  29. 29
  30. 30 UIConfig(true);
  31. 31 }
  32. 32 catch (Exception ex)
  33. 33 {
  34. 34 MessageBox.Show(ex.Message);
  35. 35
  36. 36 UIConfig(false);
  37. 37 }
  38. 38
  39. 39 }
  40. 40 /// <summary>
  41. 41 /// 启动分析
  42. 42 /// </summary>
  43. 43 private void StartAnalyzer()
  44. 44 {
  45. 45 AnalyzerThread = new Thread(new ThreadStart(analysrThreadMethod));
  46. 46 AnalyzerThread.IsBackground = true;
  47. 47 AnalyzerThread.Start();
  48. 48
  49. 49 }
  50. 50 /// <summary>
  51. 51 /// 停止
  52. 52 /// </summary>
  53. 53 private void Stop()
  54. 54 {
  55. 55 try
  56. 56 {
  57. 57 if (device != null && device.Started)
  58. 58 {
  59. 59 device.StopCapture();
  60. 60 device.Close();
  61. 61 }
  62. 62
  63. 63 isStartAnalyzer = false;
  64. 64 if (AnalyzerThread !=null && AnalyzerThread.IsAlive)
  65. 65 {
  66. 66 AnalyzerThread.Abort();
  67. 67 }
  68. 68 }
  69. 69 catch (Exception ex)
  70. 70 {
  71. 71 MessageBox.Show(ex.Message);
  72. 72 }
  73. 73 UIConfig(false);
  74. 74 }
  75. 75
  76. 76 /// <summary>
  77. 77 /// Sharpcap 获取数据包之后的回调
  78. 78 /// </summary>
  79. 79 /// <param name="sender"></param>
  80. 80 /// <param name="e"></param>
  81. 81 void device_OnPacketArrival(object sender, CaptureEventArgs e)
  82. 82 {
  83. 83 lock (threadLock)
  84. 84 {
  85. 85 bufferList.Add(e.Packet);
  86. 86 }
  87. 87 }
  88. 88
  89. 89 /// <summary>
  90. 90 /// 数据分析线程 (使用缓存方式,可避免数据堵塞)
  91. 91 /// </summary>
  92. 92
  93. 93 private void analysrThreadMethod()
  94. 94 {
  95. 95 while (isStartAnalyzer)
  96. 96 {
  97. 97 bool isShoudSleep = true;
  98. 98 lock (threadLock)
  99. 99 {
  100. 100 if (bufferList.Count != 0)
  101. 101 isShoudSleep = false;
  102. 102 }
  103. 103 if (isShoudSleep)//
  104. 104 {
  105. 105 Thread.Sleep(200);
  106. 106 }
  107. 107 else
  108. 108 {
  109. 109 List<RawCapture> tmpPacketList;
  110. 110 lock (threadLock) //获取数据
  111. 111 {
  112. 112 tmpPacketList = bufferList;
  113. 113 bufferList = new List<RawCapture>();//构建新列表
  114. 114 packetList.AddRange(tmpPacketList);
  115. 115 }
  116. 116 foreach (var i in tmpPacketList)
  117. 117 {
  118. 118 this.Invoke(new DataGridRowsShowHandler(ShowDataRows), i);
  119. 119
  120. 120 }
  121. 121 }
  122. 122 }
  123. 123 }
  124. 124
  125. 125 /// <summary>
  126. 126 /// 在datagridview中显示获取的网络数据
  127. 127 /// </summary>
  128. 128 /// <param name="packet"></param>
  129. 129 private void ShowDataRows(RawCapture packet)
  130. 130 {
  131. 131 try
  132. 132 {
  133. 133 dataGridPacket.Rows.Add(rowsBulider.Row(packet, ++packetIndex));//加载DataGridRows;
  134. 134 }
  135. 135 catch (Exception ex)
  136. 136 {
  137. 137
  138. 138 }
  139. 139 }

这里通过在抓包启动之前,预先启动一个分析线程,用于独立进行数据解析,接下来就是在DataGridView中添加数据了,这部分写的比较渣,请轻喷,毕竟是几年前的代码了,代码如下:

  1. 1 using System;
  2. 2 using System.Collections.Generic;
  3. 3 using System.Linq;
  4. 4 using System.Text;
  5. 5 using System.Windows.Forms;
  6. 6 using SharpPcap;
  7. 7 using PacketDotNet;
  8. 8 using System.Xml;
  9. 9 namespace MySniffer
  10. 10 {
  11. 11 class DataBuilder
  12. 12 {
  13. 13 //标记当前数据是否有效
  14. 14
  15. 15 #region 构建数据行
  16. 16 /// <summary>
  17. 17 /// DataGridRow
  18. 18 /// </summary>
  19. 19 /// <returns>返回字符串数据</returns>
  20. 20 public string[] Row(RawCapture rawPacket, uint packetID)
  21. 21 {
  22. 22 string[] rows = new string[6];
  23. 23
  24. 24 rows[0] = string.Format("{0:D7}", packetID);//编号
  25. 25 rows[1] = "Unknown";
  26. 26 rows[2] = rawPacket.Data.Length.ToString();//数据长度bytes
  27. 27 rows[3] = "--";
  28. 28 rows[4] = "--";
  29. 29 rows[5] = "--";
  30. 30
  31. 31 Packet packet = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data);
  32. 32
  33. 33 EthernetPacket ep = EthernetPacket.GetEncapsulated(packet);
  34. 34 if (ep != null)
  35. 35 {
  36. 36 rows[1] = "Ethernet(v2)";
  37. 37 rows[3] = Format.MacFormat(ep.SourceHwAddress.ToString());
  38. 38 rows[4] = Format.MacFormat(ep.DestinationHwAddress.ToString());
  39. 39 rows[5] = "[" + ep.Type.ToString() + "]";
  40. 40
  41. 41 #region IP
  42. 42 IpPacket ip = IpPacket.GetEncapsulated(packet);
  43. 43 if (ip != null)
  44. 44 {
  45. 45 if (ip.Version == IpVersion.IPv4)
  46. 46 {
  47. 47 rows[1] = "IPv4";
  48. 48 }
  49. 49 else
  50. 50 {
  51. 51 rows[1] = "IPv6";
  52. 52 }
  53. 53 rows[3] = ip.SourceAddress.ToString();
  54. 54 rows[4] = ip.DestinationAddress.ToString();
  55. 55 rows[5] = "[下层协议:" + ip.NextHeader.ToString() + "] [版本:" + ip.Version.ToString() + "]";
  56. 56
  57. 57 TcpPacket tcp = TcpPacket.GetEncapsulated(packet);
  58. 58 if (tcp != null)
  59. 59 {
  60. 60 rows[1] = "TCP";
  61. 61 rows[3] += " [" + tcp.SourcePort.ToString() + "]";
  62. 62 rows[4] += " [" + tcp.DestinationPort.ToString() + "]";
  63. 63
  64. 64 return rows;
  65. 65 }
  66. 66 UdpPacket udp = UdpPacket.GetEncapsulated(packet);
  67. 67 if (udp != null)
  68. 68 {
  69. 69 rows[1] = "UDP";
  70. 70 rows[3] += " [" + udp.SourcePort.ToString() + "]";
  71. 71 rows[4] += " [" + udp.DestinationPort.ToString() + "]";
  72. 72 return rows;
  73. 73 }
  74. 74
  75. 75 ICMPv4Packet icmpv4 = ICMPv4Packet.GetEncapsulated(packet);
  76. 76 if (icmpv4 != null)
  77. 77 {
  78. 78 rows[1] = "ICMPv4";
  79. 79 rows[5] = "[校验:" + icmpv4.Checksum.ToString() + "] [类型:" + icmpv4.TypeCode.ToString() + "] [序列号:" + icmpv4.Sequence.ToString() + "]";
  80. 80 return rows;
  81. 81 }
  82. 82 ICMPv6Packet icmpv6 = ICMPv6Packet.GetEncapsulated(packet);
  83. 83 if (icmpv6 != null)
  84. 84 {
  85. 85 rows[1] = "ICMPv6";
  86. 86 rows[5] = "[Code:" + icmpv6.Code.ToString() + "] [Type" + icmpv6.Type.ToString() + "]";
  87. 87 return rows;
  88. 88 }
  89. 89 IGMPv2Packet igmp = IGMPv2Packet.GetEncapsulated(packet);
  90. 90 if (igmp != null)
  91. 91 {
  92. 92 rows[1] = "IGMP";
  93. 93 rows[5] = "[只适用于IGMPv2] [组地址:" + igmp.GroupAddress.ToString() + "] [类型:" + igmp.Type.ToString() + "]";
  94. 94 return rows;
  95. 95 }
  96. 96 return rows;
  97. 97 }
  98. 98 #endregion
  99. 99
  100. 100 ARPPacket arp = ARPPacket.GetEncapsulated(packet);
  101. 101 if (arp != null)
  102. 102 {
  103. 103 rows[1] = "ARP";
  104. 104 rows[3] = Format.MacFormat(arp.SenderHardwareAddress.ToString());
  105. 105 rows[4] = Format.MacFormat(arp.TargetHardwareAddress.ToString());
  106. 106 rows[5] = "[Arp操作方式:" + arp.Operation.ToString() + "] [发送者:" + arp.SenderProtocolAddress.ToString() + "] [目标:" + arp.TargetProtocolAddress.ToString() + "]";
  107. 107 return rows;
  108. 108 }
  109. 109 WakeOnLanPacket wp = WakeOnLanPacket.GetEncapsulated(packet);
  110. 110 if (wp != null)
  111. 111 {
  112. 112 rows[1] = "Wake On Lan";
  113. 113 rows[3] = Format.MacFormat(ep.SourceHwAddress.ToString());
  114. 114 rows[4] = Format.MacFormat(wp.DestinationMAC.ToString());
  115. 115 rows[5] = "[唤醒网络地址:" + wp.DestinationMAC.ToString() + "] [有效性:" + wp.IsValid().ToString() + "]";
  116. 116 return rows;
  117. 117 }
  118. 118 PPPoEPacket poe = PPPoEPacket.GetEncapsulated(packet);
  119. 119 if (poe != null)
  120. 120 {
  121. 121 rows[1] = "PPPoE";
  122. 122 rows[5] = poe.Type.ToString() + " " + poe.Version.ToString();
  123. 123 return rows;
  124. 124
  125. 125 }
  126. 126 LLDPPacket llp = LLDPPacket.GetEncapsulated(packet);
  127. 127 if (llp != null)
  128. 128 {
  129. 129 rows[1] = "LLDP";
  130. 130 rows[5] = llp.ToString();
  131. 131 return rows;
  132. 132 }
  133. 133 return rows;
  134. 134 }
  135. 135 //链路层
  136. 136 PPPPacket ppp = PPPPacket.GetEncapsulated(packet);
  137. 137 if (ppp != null)
  138. 138 {
  139. 139 rows[1] = "PPP";
  140. 140 rows[3] = "--";
  141. 141 rows[4] = "--";
  142. 142 rows[5] = "协议类型:" + ppp.Protocol.ToString();
  143. 143 return rows;
  144. 144
  145. 145 }
  146. 146 //PPPSerial
  147. 147 PppSerialPacket ppps = PppSerialPacket.GetEncapsulated(packet);
  148. 148 if (ppps != null)
  149. 149 {
  150. 150 rows[1] = "PPP";
  151. 151 rows[3] = "--";
  152. 152 rows[4] = "0x" + ppps.Address.ToString("X2");
  153. 153 rows[5] = "地址:" + ppps.Address.ToString("X2") + " 控制:" + ppps.Control.ToString() + " 协议类型:" + ppps.Protocol.ToString();
  154. 154 return rows;
  155. 155 }
  156. 156 //Cisco HDLC
  157. 157 CiscoHDLCPacket hdlc = CiscoHDLCPacket.GetEncapsulated(packet);
  158. 158 if (hdlc != null)
  159. 159 {
  160. 160 rows[1] = "Cisco HDLC";
  161. 161 rows[3] = "--";
  162. 162 rows[4] = "0x" + hdlc.Address.ToString("X2");
  163. 163 rows[5] = "地址:" + hdlc.Address.ToString("X2") + " 控制:" + hdlc.Control.ToString() + " 协议类型:" + hdlc.Protocol.ToString();
  164. 164 return rows;
  165. 165 }
  166. 166 #warning 需要测试
  167. 167 PacketDotNet.Ieee80211.MacFrame ieee = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data) as PacketDotNet.Ieee80211.MacFrame;
  168. 168 if (ieee != null)
  169. 169 {
  170. 170 rows[1] = "IEEE802.11 MacFrame";
  171. 171 rows[3] = "--";
  172. 172 rows[4] = "--";
  173. 173 rows[5] = "帧校验序列:" + ieee.FrameCheckSequence.ToString() + " 封装帧:" + ieee.FrameControl .ToString();
  174. 174 return rows;
  175. 175 }
  176. 176 PacketDotNet.Ieee80211.RadioPacket ieeePacket = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data) as PacketDotNet.Ieee80211.RadioPacket;
  177. 177 if (ieeePacket != null)
  178. 178 {
  179. 179 rows[1] = "IEEE Radio";
  180. 180 rows[5] = "Version=" + ieeePacket.Version.ToString();
  181. 181 }
  182. 182 LinuxSLLPacket linux = Packet.ParsePacket(rawPacket.LinkLayerType, rawPacket.Data) as LinuxSLLPacket;
  183. 183 if (linux != null)
  184. 184 {
  185. 185 rows[1] = "LinuxSLL";
  186. 186 rows[5] = "Tyep=" + linux.Type.ToString() + " Protocol=" + linux.EthernetProtocolType.ToString();
  187. 187 }
  188. 188 return rows;
  189. 189 }
  190. 190 }
  191. 191 #endregion
  192. 192
  193. 193
  194. 194
  195. 195
  196. 196 }

虽然写的比较渣,但是思路还是蛮清晰的,额~~有砖头~~~~~

先不管了,来一起看看结果吧

图4 采集到网络数据

终于有点激动了,那么我们接下来就是要实现详细的数据了,不过看了上面的方式代码的解析方式,你会不会有点想法呢。好吧,我这边只把TCP的解析方式放在这里了

  1. 1 //Tcp
  2. 2 TreeNode TCPNode;
  3. 3 TreeNode TcpFlagNode;
  4. 4 TreeNode TcpChecksumNode;
  5. 5 TreeNode TcpOptionsNode;
  6. 6 private void TCP(TcpPacket tcp)
  7. 7 {
  8. 8 if (TCPNode == null)
  9. 9 {
  10. 10 TCPNode = CreatNode("TCP", 6);
  11. 11 }
  12. 12 TCPNode.Nodes.Clear();
  13. 13 //port
  14. 14 TCPNode.Nodes.Add("Source Port: " + tcp.SourcePort.ToString());
  15. 15 TCPNode.Nodes.Add("Destination Port: " + tcp.DestinationPort.ToString());
  16. 16 // Seq and Ack
  17. 17 TCPNode.Nodes.Add("Sequence Number: " + tcp.SequenceNumber.ToString() + " [0x" + tcp.SequenceNumber.ToString("X") + "]");
  18. 18 TCPNode.Nodes.Add("Acknowledgement Number: " + tcp.AcknowledgmentNumber.ToString() + " [0x" + tcp.AcknowledgmentNumber.ToString("X") + "]");
  19. 19 //Data Offset
  20. 20 TCPNode.Nodes.Add("Data Offset: " + (tcp.DataOffset * 4).ToString() + " [0x" + tcp.DataOffset.ToString("X") + "]");
  21. 21 //Flags
  22. 22 #region Flags
  23. 23 if (TcpFlagNode == null)
  24. 24 {
  25. 25 TcpFlagNode = new TreeNode();
  26. 26 }
  27. 27 TcpFlagNode.Nodes.Clear();
  28. 28 TcpFlagNode.Text = "Flags: [" + Format.TcpFlagType(tcp) + "] [0x" + string.Format("{0:X2}", tcp.AllFlags) + "]";
  29. 29 TcpFlagNode.Nodes.Add("000. .... .... = Reserved");
  30. 30 TcpFlagNode.Nodes.Add("...0 .... .... = Nonce");
  31. 31 TcpFlagNode.Nodes.Add(".... " + Format.getStaus(tcp.CWR) + "... .... = CWR");
  32. 32 TcpFlagNode.Nodes.Add(".... ." + Format.getStaus(tcp.ECN) + ".. .... = ECN-Echo");
  33. 33 TcpFlagNode.Nodes.Add(".... .." + Format.getStaus(tcp.Urg) + ". .... = URG");
  34. 34 TcpFlagNode.Nodes.Add(".... ..." + Format.getStaus(tcp.Ack) + " .... = ACK");
  35. 35 TcpFlagNode.Nodes.Add(".... .... " + Format.getStaus(tcp.Psh) + "... = PSH");
  36. 36 TcpFlagNode.Nodes.Add(".... .... ." + Format.getStaus(tcp.Rst) + ".. = RST");
  37. 37 TcpFlagNode.Nodes.Add(".... .... .." + Format.getStaus(tcp.Syn) + ". = SYN");
  38. 38 TcpFlagNode.Nodes.Add(".... .... ..." + Format.getStaus(tcp.Fin) + " = FIN");
  39. 39 TCPNode.Nodes.Add(TcpFlagNode);
  40. 40 #endregion
  41. 41 //WinSize
  42. 42 TCPNode.Nodes.Add("Window Size: " + tcp.WindowSize.ToString());
  43. 43 //check Sum
  44. 44 if (TcpChecksumNode == null)
  45. 45 {
  46. 46 TcpChecksumNode = new TreeNode();
  47. 47 }
  48. 48 TcpChecksumNode.Nodes.Clear();
  49. 49 TcpChecksumNode.Text = "Checksum: 0x" + tcp.Checksum.ToString("X") + " [" + (tcp.ValidChecksum ? "Valid" : "Invalid") + "]";
  50. 50 if (!tcp.ValidChecksum)
  51. 51 {
  52. 52 TCPNode.BackColor = TcpChecksumNode.BackColor = System.Drawing.Color.Red;
  53. 53 TCPNode.ForeColor = TcpChecksumNode.ForeColor = System.Drawing.Color.White;
  54. 54 }
  55. 55 else
  56. 56 {
  57. 57 TCPNode.BackColor = TcpChecksumNode.BackColor = Tree.BackColor;
  58. 58 TCPNode.ForeColor = TcpChecksumNode.ForeColor = Tree.ForeColor;
  59. 59 }
  60. 60
  61. 61 TcpChecksumNode.Nodes.Add("Correct: " + tcp.ValidTCPChecksum.ToString());
  62. 62 TCPNode.Nodes.Add(TcpChecksumNode);
  63. 63 //Urgent
  64. 64 TCPNode.Nodes.Add("Urgent Pointer: " + tcp.UrgentPointer.ToString() + " [0x" + tcp.UrgentPointer.ToString("X") + "]");
  65. 65 //Options
  66. 66 if (tcp.Options.Length > 0)
  67. 67 {
  68. 68 if (TcpOptionsNode == null)
  69. 69 {
  70. 70 TcpOptionsNode = new TreeNode();
  71. 71 }
  72. 72 TcpOptionsNode.Nodes.Clear();
  73. 73 TcpOptionsNode.Text = "Options: " + tcp.Options.Length.ToString() + " bytes";
  74. 74 // [0x" + BitConverter.ToString(tcp.Options).Replace("-", "").PadLeft(12, '0') + "]
  75. 75 if (tcp.OptionsCollection != null)
  76. 76 {
  77. 77 var tmpColl = tcp.OptionsCollection;
  78. 78 for (int i = 0; i < tmpColl.Count; i++)
  79. 79 {
  80. 80 TcpOptionsNode.Nodes.Add(tmpColl[i].ToString());
  81. 81 }
  82. 82 }
  83. 83 TCPNode.Nodes.Add(TcpOptionsNode);
  84. 84 }
  85. 85 Tree.Nodes.Add(TCPNode);
  86. 86
  87. 87
  88. 88 AppNode(tcp.PayloadData, tcp.SourcePort, tcp.DestinationPort);
  89. 89 }

好了接下来让我们看看最终的结果吧

图5 带有数据协议解析的成果图

接下来就是一个关于文件存取的功能,毕竟可以把数据保存下来也是一件很酷的事情,(好吧,我是真的想不出一个好的理由……)

  1. 1 //打开文件
  2. 2 private void btnOpen_Click(object sender, EventArgs e)
  3. 3 {
  4. 4 OpenFileDialog od = new OpenFileDialog();
  5. 5 od.Filter = "pcap文件|*.pcap";
  6. 6
  7. 7 if (od.ShowDialog() == DialogResult.OK)
  8. 8 {
  9. 9 Clear();
  10. 10
  11. 11 ICaptureDevice offDev = new SharpPcap.LibPcap.CaptureFileReaderDevice(od.FileName);
  12. 12 RawCapture tempPacket;
  13. 13 offDev.Open();
  14. 14 while ((tempPacket = offDev.GetNextPacket()) != null)
  15. 15 {
  16. 16 packetList.Add(tempPacket);
  17. 17 ShowDataRows(tempPacket);
  18. 18 }
  19. 19 offDev.Close();
  20. 20
  21. 21 }
  22. 22 }
  23. 23
  24. 24
  25. 25 //文件保存
  26. 26 private void btnSave_Click(object sender, EventArgs e)
  27. 27 {
  28. 28 SaveFileDialog sd = new SaveFileDialog();
  29. 29 sd.Filter = "Pcap文件|*.pcap";
  30. 30 if (sd.ShowDialog() == DialogResult.OK)
  31. 31 {
  32. 32 var offDev = new SharpPcap.LibPcap.CaptureFileWriterDevice(sd.FileName);
  33. 33 foreach (var i in packetList)
  34. 34 {
  35. 35 offDev.Write(i);
  36. 36 }
  37. 37 MessageBox.Show("文件保存成功", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
  38. 38 }
  39. 39 }

因为这里我们是直接通过Sharppcap调用winpcap内置的数据包存取方式,这样的好处是,我们可以用Wrieshark等一些其他抓包工具打开这些文件,当然如果你愿意也可以用自己的方式存取,只要保证在内存中可以转为RawCapture的数据列表就可以了

 

到这里了,制作一个简单的协议分析基本是完成了,这里是代码下载地址:http://yun.baidu.com/s/1dDDELzF

最后是一些个别说明,我们在监听网卡的时候有个模式的选项

  1. DeviceMode devMode = DeviceMode.Promiscuous;//数据采集模式

这里有连个模式一个常规模式 DeviceMode.Normal 和一个混杂模式 DeviceMode.Promiscuous主要是用于判断在网卡的数据监听方式,混杂模式就是接收所有经过网卡的数据包,包括不是发给本机的包。默认情况下网卡只把发给本机的包(包括广播包)传递给上层程序,其它的包一律丢弃。简单的讲,混杂模式就是指网卡能接受所有通过它的数据流,不管是什么格式,什么地址的。事实上,计算机收到数据包后,由网络层进行判断,确定是递交上层(传输层),还是丢弃,还是递交下层(数据链路层、MAC子层)转发。(这段来自百度)

还有一个就是关于超时设定,我们直接在程序中定义为1000ms 也就是1秒,也就是说通过winpcap每个1s向程序推送一次监听到的数据,这个值一定要合理设置,如果设置过短,就可能以为频繁提交数据造成性能开销和引起丢包,而如果过长再回造成界面响应慢,总之自己看情况设定吧

好了今天就写到这里吧,不足之处还请指正,祝你阅读愉快

NetAnalyzer下载地址

NetAnalzyer交流群:39753670 (PS 只提供交流平台,群主基本不说话^_^)

[转载请保留作者信息  作者:冯天文  网址:http://www.cnblogs.com/twzy/p/4769797.html ]

 

C#版的抓包软件的更多相关文章

  1. NetAnalyzer笔记 之 四. C#版的抓包软件

    [创建时间:2015-09-10 22:37:04] NetAnalyzer下载地址 不好意思啊,NetAnalyzer停更有点长了,今天继续填坑^&^ NetAnalyzer实现结构 在上一 ...

  2. 如何在Windows系统上用抓包软件Wireshark截获iPhone等网络通讯数据

    http://www.jb51.net/os/windows/189090.html 今天给大家介绍一种如何在Windows操作系统上使用著名的抓包工具软件Wireshark来截获iPhone.iPa ...

  3. Mac用户抓包软件Charles 4.0 破解 以及 抓取Https链接设置

    相信大家曾经都是Window的用户,作为前端哪能没有一款抓包工具,抓包工具可以非常便捷的帮助我们分析接口返回报文数据,快速定位问题. 曾经横扫window用户的Fiddler便是我们的挚爱,然而,作为 ...

  4. CatchPacket网络抓包软件

    CatchPacket网络抓包软件  qq  22945088431.技术特点:基于WinPcap库,c# winform2.实现获取机器所有网卡,可任意选择监听3.可以捕获常见网络协议arp dns ...

  5. 抓包软件PowerSniff开发计划

    目前抓包的工具不顺手: (1)smartsniff, minisniffer不支持插件 (2)wireshark,omnipeek插件过于复杂,还有不是要装驱动就是admin权限 打算重写一个,第一个 ...

  6. 手机抓包软件Charles安装使用实例 (流媒体播放测试可去下载的时刻检测)

    手机抓包软件Charles安装使用实例   浏览:5258 发布日期:2015/07/17 分类:技术分享 关键字: 手机抓包软件 Charles 大胡子的博客Charles安装使用实例 Charle ...

  7. 比Wireshark更轻量、更方便的抓包软件:Charles

    转:http://blog.csdn.net/lixing333/article/details/42776187 之前写过一篇通过Wireshark进行抓包,分析网络连接的文章<通过WireS ...

  8. 第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解

    第三百三十节,web爬虫讲解2—urllib库爬虫—实战爬取搜狗微信公众号—抓包软件安装Fiddler4讲解 封装模块 #!/usr/bin/env python # -*- coding: utf- ...

  9. 分享三个USB抓包软件---Bus Hound,USBlyzer 和-USBTrace(转)

    源:分享三个USB抓包软件---Bus Hound,USBlyzer 和-USBTrace Bus Hound官方下载地址:http://perisoft.net/bushound/Bus Hound ...

随机推荐

  1. [Elasticsearch] 控制相关性 (一) - 后面的相关度分值理论计算

    从第一章翻译Elasticsearch官方指南Controlling Relevance一章. 控制相关度(Controlling Relevance) 对于仅处理结构化数据(比方日期.数值和字符枚举 ...

  2. SQL注入问题

    斌斌 (给我写信) 原创博文(http://blog.csdn.net/binbinxyz),转载请注明出处! 背景:对于ibaits参数引用可以使用#和$两种写法,其中#写法会采用预编译方式,将转义 ...

  3. 【小白的java成长系列】——顶级类Object源代码分析

    首先来说一下api文档使用,api这个词对有一定开发经验的java编程人员来说是非常喜爱的~ java当然也提供了api开发文档,下载地址:http://www.oracle.com/technetw ...

  4. JDK源码学习系列02----AbstractStringBuilder

     JDK源码学习系列02----AbstractStringBuilder 因为看StringBuffer 和 StringBuilder 的源码时发现两者都继承了AbstractStringBuil ...

  5. 第三届蓝桥杯Java高职组决赛第三题

    题目描述: 某少年宫引进了一批机器人小车.可以接受预先输入的指令,按指令行动.小车的基本动作很简单,只有3种:左转(记为L),右转(记为R),向前走若干厘米(直接记数字). 例如,我们可以对小车输入如 ...

  6. php编码规范个人小结

    1.原生态代码或者类的头上,注明作者,关键算法计算过程 例如 /** *@author zengmoumou *功能:根据列表ip,取得ip对应的运营商,省,市,县 */ 2.变量尽量用英文单词的组合 ...

  7. 【原创】编写多线程Python爬虫来过滤八戒网上的发布任务

    目标: 以特定语言技术为关键字,爬取八戒网中网站设计开发栏目下发布的任务相关信息 需求: 用户通过设置自己感兴趣的关键字或正则表达式,来过滤信息. 我自己选择的是通过特定语言技术作为关键字,php.j ...

  8. POJ 2485 Highways (prim最小生成树)

    对于终于生成的最小生成树中最长边所连接的两点来说 不存在更短的边使得该两点以不论什么方式联通 对于本题来说 最小生成树中的最长边的边长就是使整个图联通的最长边的边长 由此可知仅仅要对给出城市所抽象出的 ...

  9. Android自带样式

    Android系统自带样式: android:theme="@android:style/Theme.Dialog" 将一个Activity显示为对话框模式 android:the ...

  10. 【DataStructure】The description of Java Collections Framework

    The Java Connections FrameWork is a group of class or method and interfacs in the java.util package. ...