zoukankan      html  css  js  c++  java
  • 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 ]

  • 相关阅读:
    〖Python〗-- Tornado自定义session组件
    〖Python〗-- Tornado异步非阻塞
    〖Python〗-- Tornado基础
    〖Python〗-- Flask
    〖Python〗-- 设计模式
    〖Python〗-- Celery分布式任务队列
    〖Demo〗-- CosPlayPermission
    05——wepy框架中的一些细节
    04——wepy框架搭建
    03——微信小程序官方demo讲解——page部分
  • 原文地址:https://www.cnblogs.com/twzy/p/4769797.html
Copyright © 2011-2022 走看看