NetAnalyzer筆記 之 四. 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         private void loadDevice()// 獲取網卡方法
 2         {
 3             try
 4             {
 5                 foreach (var i in CaptureDeviceList.Instance)
 6                 {
 7                     comDeviceList.Items.Add(i.Description);  //在combox中添加
 8                 }
 9                 if (comDeviceList.Items.Count > 0)
10                 {
11                     comDeviceList.SelectedIndex = 0;//自動選中第一個
12                 }
13             }
14             catch (Exception ex)
15             {
16                 MessageBox.Show(ex.Message);
17                 return;
18             }
19         }

 

我們通過調用SharpPcap.CaptureDeviceList.Instance 單例,獲取一個包含所用網卡的列表CaptureDeviceList,然后把以此把網卡的描述信息添加到頂部工具欄comDeviceList 中

在代碼中我們加一個全局變量device用來指示當前控制的網卡,

1         ICaptureDevice device;// 定義設備

 

所以當我們每次去選擇不同的網卡時調用下面的方法

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

完成運行如圖

                                   圖3獲取的網卡以及其信息

接下來我們直接來點精彩的,加入如下代碼:

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

 

這里通過在抓包啟動之前,預先啟動一個分析線程,用於獨立進行數據解析,接下來就是在DataGridView中添加數據了,這部分寫的比較渣,請輕噴,畢竟是幾年前的代碼了,代碼如下:

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

 

雖然寫的比較渣,但是思路還是蠻清晰的,額~~有磚頭~~~~~

先不管了,來一起看看結果吧

                                             圖4 采集到網絡數據

 終於有點激動了,那么我們接下來就是要實現詳細的數據了,不過看了上面的方式代碼的解析方式,你會不會有點想法呢。好吧,我這邊只把TCP的解析方式放在這里了

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

 

好了接下來讓我們看看最終的結果吧

 

                                圖5 帶有數據協議解析的成果圖

接下來就是一個關於文件存取的功能,畢竟可以把數據保存下來也是一件很酷的事情,(好吧,我是真的想不出一個好的理由……)

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

 

因為這里我們是直接通過Sharppcap調用winpcap內置的數據包存取方式,這樣的好處是,我們可以用Wrieshark等一些其他抓包工具打開這些文件,當然如果你願意也可以用自己的方式存取,只要保證在內存中可以轉為RawCapture的數據列表就可以了

 

到這里了,制作一個簡單的協議分析基本是完成了,這里是代碼下載地址:http://yun.baidu.com/s/1dDDELzF

最后是一些個別說明,我們在監聽網卡的時候有個模式的選項

 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 ]


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM