1. 程式人生 > >C# 非同步多執行緒 sharpPcap 抓包

C# 非同步多執行緒 sharpPcap 抓包

需要在電腦上安裝Winpcap 還沒有寫完

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using SharpPcap;
using PacketDotNet;

namespace Network_monitoring
{
    public partial class Sniffers : Form
    {

        private List<RawCapture> PacketQueue = new List<RawCapture>();
        private System.Threading.Thread backgroundThread;
        private DateTime LastStatisticsOutput;
        private TimeSpan LastStatisticsInterval = new TimeSpan(0, 0, 2);
        private CaptureDeviceList devices;
        private ICaptureDevice dev;
        private static int number = 0;
        private ICaptureStatistics captureStatistics;
        private bool statisticsUiNeedsUpdate = false;
        private PacketArrivalEventHandler arrivalEventHandler;
        private Queue<PacketWrapper> myPackets;
        private DeviceMode mode;
        System.Collections.ArrayList PacketList = new System.Collections.ArrayList();
        public int TotalCount = 0;
        public int ARPCount = 0;
        public int EthernetCount = 0;
        public int ICMPCount = 0;
        public int IGMPCount = 0;
        public int IPCount = 0;
        public int TCPCount = 0;
        public int UDPCount = 0;

        public Sniffers()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
            this.devices = CaptureDeviceList.Instance;
            foreach (var dev in devices)
            {
                var des = dev.Description.Split('\'');
                var str = String.Format("{0}:{1}", dev.Name.ToString(), des[1]);
                this.comboBox1.Items.Add(str);
            }
            myPackets = new Queue<PacketWrapper>();
        }

        /// <summary>
        /// When true the background thread will terminate
        /// </summary>
        /// <param name="args">
        /// A <see cref="System.String"/>
        /// </param>
        private bool BackgroundThreadStop;

        /// <summary>
        /// Object that is used to prevent two threads from accessing
        /// PacketQueue at the same time
        /// </summary>
        /// <param name="args">
        /// A <see cref="System.String"/>
        /// </param>
        private object QueueLock = new object();

        /// <summary>
        /// The queue that the callback thread puts packets in. Accessed by
        /// the background thread when QueueLock is held
        /// </summary>
        

        public class PacketWrapper
        {
            public PacketDotNet.EthernetPacket ePacket;
            public string time;
            public DateTime times;
            public string timess;
            public string timesss;
            public DateTime timessss;
            public RawCapture p;
            public string protocol;
            public string len;
            public string SourAddress;
            public string DestionAddress;
            public string SourPort;
            public string DestionPort;
            public PacketWrapper(int count, RawCapture p)
            {
                var packet = PacketDotNet.EthernetPacket.ParsePacket(p.LinkLayerType, p.Data);
                this.ePacket = (PacketDotNet.EthernetPacket)packet;
                this.p = p;
                this.No = count;
                this.len = packet.Bytes.Length.ToString();
                this.times = Convert.ToDateTime("08:00:00");
                this.timesss = p.Timeval.Date.ToString();
                this.timess = timesss.Substring(Convert.ToInt32(timesss.IndexOf(" ") + 1));
                this.timessss = Convert.ToDateTime(timess);
                this.timessss = timessss.AddHours(times.Hour);
                this.time = this.timess.Replace(timess, timessss.ToString());
                this.protocol = "";
                getDetail();
            }

            public void getDetail()
            {
                var packet = Packet.ParsePacket(p.LinkLayerType, p.Data);
                this.protocol = this.ePacket.Type.ToString();
                var ipPacket = PacketDotNet.IpPacket.GetEncapsulated(packet);
                if (ipPacket != null)
                {
                    this.protocol = ipPacket.Protocol.ToString();
                    this.SourAddress = ipPacket.SourceAddress.ToString();
                    this.DestionAddress = ipPacket.DestinationAddress.ToString();
                }
                else
                {
                    this.SourAddress = "Null";
                    this.DestionAddress = "Null";
                }
                if (this.protocol == "TCP")
                {
                    PacketDotNet.TcpPacket tcppacket = TcpPacket.GetEncapsulated(packet);
                    this.SourPort = tcppacket.SourcePort.ToString();
                    this.DestionPort = tcppacket.DestinationPort.ToString();
                    if (tcppacket != null)
                    {
                        int Sport = tcppacket.SourcePort;
                        int Dport = tcppacket.DestinationPort;
                        if (Sport == 80 || Sport == 8080 || Sport == 3128)
                        {
                            this.protocol = "HTTP";
                        }
                        else if (Sport == 21)
                        {
                            this.protocol = "FTP";
                        }
                        else if (Sport == 25)
                        {
                            this.protocol = "SMTP";
                        }
                        else if (Sport == 110)
                        {
                            this.protocol = "POP3";
                        }
                    }
                }
                else if (this.protocol == "UDP")
                {
                    PacketDotNet.UdpPacket udppacket = UdpPacket.GetEncapsulated(packet);
                    this.SourPort = udppacket.SourcePort.ToString();
                    this.DestionPort = udppacket.DestinationPort.ToString();
                    if (udppacket != null)
                    {
                        int port = udppacket.SourcePort;

                        if (port == 53)
                        {
                            this.protocol = "DNS";
                        }
                    }
                }
                else if (this.protocol == "Arp")
                {
                    this.SourPort = "Null";
                    this.DestionPort = "Null";
                }
                else if (this.protocol == "ICMP")
                {
                    this.SourPort = "Null";
                    this.DestionPort = "Null";
                }
                else if (this.protocol == "IGMP")
                {
                    this.SourPort = "Null";
                    this.DestionPort = "Null";
                }
                else if (this.protocol == "Ethernet")
                {
                    this.SourPort = "Null";
                    this.DestionPort = "Null";
                }
            }

            public int No { get; private set; }
            public string Protocol { get { return protocol; } }
            public string Length { get { return len; } }
            public string SourceA { get { return SourAddress; } }
            public string Sourse { get { return ePacket.SourceHwAddress.ToString(); } }
            public string SourceP { get { return SourPort; } }
            public string DestionA { get { return DestionAddress; } }
            public string Destination { get { return ePacket.DestinationHwAddress.ToString(); } }
            public string destionP { get { return DestionPort; } }
            public string Time { get { return time; } }
            //public string Times { get { return timess; } }
        }

        /// <summary>
        /// Checks for queued packets. If any exist it locks the QueueLock, saves a
        /// reference of the current queue for itself, puts a new queue back into
        /// place into PacketQueue and unlocks QueueLock. This is a minimal amount of
        /// work done while the queue is locked.
        ///
        /// The background thread can then process queue that it saved without holding
        /// the queue lock.
        /// </summary>
        private void BackgroundThread()
        {
            while (!BackgroundThreadStop)
            {
                bool shouldSleep = true;

                lock (QueueLock)
                {
                    if (PacketQueue.Count != 0)
                    {
                        shouldSleep = false;
                    }
                }

                if (shouldSleep)
                {
                    System.Threading.Thread.Sleep(250);
                }
                else
                {
                    List<RawCapture> ourQueue;
                    lock (QueueLock)
                    {
                        ourQueue = PacketQueue;
                        PacketQueue = new List<RawCapture>();
                    }

                    foreach (var packet in ourQueue)
                    {
                        var packetWrapper = new PacketWrapper(number, packet);
                        //this.label2.Text = packetWrapper.timess.ToString();
                        this.BeginInvoke(new MethodInvoker(delegate
                        {
                            ListViewItem aItem = new ListViewItem(packetWrapper.No.ToString());
                            if (this.comboBox2.Text == "")
                            {
                                aItem.SubItems.Add(packetWrapper.Protocol);
                                aItem.SubItems.Add(packetWrapper.Length);
                                aItem.SubItems.Add(packetWrapper.SourceA);
                                aItem.SubItems.Add(packetWrapper.Sourse);
                                aItem.SubItems.Add(packetWrapper.SourceP);
                                aItem.SubItems.Add(packetWrapper.DestionA);
                                aItem.SubItems.Add(packetWrapper.Destination);
                                aItem.SubItems.Add(packetWrapper.destionP);
                                aItem.SubItems.Add(packetWrapper.Time);
                                this.listView1.Items.Add(aItem);
                                myPackets.Enqueue(packetWrapper);
                            }
                            else if (packetWrapper.Protocol == this.comboBox2.Text)
                            {
                                aItem.SubItems.Add(this.comboBox2.Text);
                                aItem.SubItems.Add(packetWrapper.Length);
                                aItem.SubItems.Add(packetWrapper.SourceA);
                                aItem.SubItems.Add(packetWrapper.Sourse);
                                aItem.SubItems.Add(packetWrapper.SourceP);
                                aItem.SubItems.Add(packetWrapper.DestionA);
                                aItem.SubItems.Add(packetWrapper.Destination);
                                aItem.SubItems.Add(packetWrapper.destionP);
                                aItem.SubItems.Add(packetWrapper.Time);
                                this.listView1.Items.Add(aItem);
                                myPackets.Enqueue(packetWrapper);
                            }
                            //aItem.SubItems.Add(packetWrapper.Length);
                            //aItem.SubItems.Add(packetWrapper.SourceA);
                            //aItem.SubItems.Add(packetWrapper.Sourse);
                            //aItem.SubItems.Add(packetWrapper.SourceP);
                            //aItem.SubItems.Add(packetWrapper.DestionA);
                            //aItem.SubItems.Add(packetWrapper.Destination);
                            //aItem.SubItems.Add(packetWrapper.destionP);
                            //aItem.SubItems.Add(packetWrapper.Time);
                            //this.listView1.Items.Add(aItem);
                            //myPackets.Enqueue(packetWrapper);
                        }
                        ));
                        number++;

                        this.BeginInvoke(new MethodInvoker(delegate
                        {
                            //bs.DataSource = myPackets;
                            if (packetWrapper.protocol == "TCP" || packetWrapper.protocol == "HTTP" || packetWrapper.protocol == "SMTP" || packetWrapper.protocol == "POP3" || packetWrapper.protocol == "FTP")
                            {
                                TCPCount++;
                            }
                            else if (packetWrapper.protocol == "UDP" || packetWrapper.protocol == "DNS")
                            {
                                UDPCount++;
                            }
                            else if (packetWrapper.protocol == "Arp")
                            {
                                ARPCount++;
                            }
                            else if (packetWrapper.protocol == "ICMP" || packetWrapper.protocol == "ICMPV6")
                            {
                                ICMPCount++;
                            }
                            else if (packetWrapper.protocol == "IGMP" || packetWrapper.protocol == "IGMPV6")
                            {
                                IGMPCount++;
                            }
                            else if (packetWrapper.protocol == "IP")
                            {
                                IPCount++;
                            }
                            else if (packetWrapper.protocol == "Ethernet")
                            {
                                EthernetCount++;
                            }
                        }
                       ));
                    }

                    this.BeginInvoke(new MethodInvoker(delegate
                    {
                        TotalCount = TCPCount + UDPCount + ARPCount + ICMPCount + IGMPCount + IPCount + EthernetCount;
                        this.Statistics();
                        
                        //if (showFirst && myPackets.Count != 0)
                        //{
                        //    PacketWrapper pw = myPackets.First();
                        //    if (pw == null)
                        //    {
                        //        return;
                        //    }
                        //    var packet = Packet.ParsePacket(pw.p.LinkLayerType, pw.p.Data);
                        //    this.tbShowData.Text = packet.PrintHex();
                        //    changeTreeview(pw);
                        //    showFirst = false;
                        //}
                    }
                  ));
                    if (statisticsUiNeedsUpdate)
                    {
                        statisticsUiNeedsUpdate = false;
                    }
                }
            }
        }
       

        

        public class PacketProcesser
        {
            public PacketWrapper pw;
            public int num;
            public int totalLength;
            public string arrvialTime;
            public string epochTime;
            public List<string> protocols;
            public string data;
            public MyEthernetPacket etherPacket;
            public MyIpPacket ipPacket;
            public MyTCPPacket tcpPacket;
            public MyUDPPacket udpPacket;

            public PacketProcesser(PacketWrapper packet)
            {
                this.pw = packet;
                this.num = packet.No;
                RawCapture rw = packet.p;
                this.protocols = new List<string>();
                PacketDotNet.Packet temp = PacketDotNet.Packet.ParsePacket(rw.LinkLayerType, rw.Data);
                PacketDotNet.EthernetPacket ePacket = (PacketDotNet.EthernetPacket)PacketDotNet.EthernetPacket.ParsePacket(rw.LinkLayerType, rw.Data);
                this.totalLength = temp.Bytes.Length;
                this.arrvialTime = rw.Timeval.ToString();
                this.epochTime = packet.time; //rw.Timeval.Date.ToString();
                this.data = "";
                if (ePacket != null)
                {
                    this.etherPacket = new MyEthernetPacket(ePacket);
                    this.protocols.Add(ePacket.Type.ToString());
                }

                var ipPack = PacketDotNet.IpPacket.GetEncapsulated(temp);
                if (ipPack != null)
                {
                    this.protocols.Add(ipPack.Protocol.ToString());
                    this.ipPacket = new MyIpPacket(ipPack);
                    if (ipPack.Protocol.ToString() == "TCP")
                    {
                        PacketDotNet.TcpPacket tcppacket = TcpPacket.GetEncapsulated(temp);
                        if (tcppacket != null)
                        {
                            this.tcpPacket = new MyTCPPacket(tcppacket);
                            int port = tcppacket.SourcePort;

                            if (port == 80 || port == 8080 || port == 3128)
                            {
                                this.protocols.Add("HTTP");
                            }
                            else if (port == 21)
                            {
                                this.protocols.Add("FTP");
                            }
                            else if (port == 25)
                            {
                                this.protocols.Add("SMTP");
                            }
                            else if (port == 110)
                            {
                                this.protocols.Add("POP3");
                            }
                        }

                    }
                    else if (ipPack.Protocol.ToString() == "UDP")
                    {
                        PacketDotNet.UdpPacket udppacket = UdpPacket.GetEncapsulated(temp);
                        if (udppacket != null)
                        {
                            this.udpPacket = new MyUDPPacket(udppacket);

                            int port = udppacket.SourcePort;

                            if (port == 53)
                            {
                                this.protocols.Add("DNS");
                            }
                        }
                    }
                }
                else
                {
                    this.ipPacket = null;
                }
            }

        }

       

        private void button1_Click(object sender, EventArgs e)
        {
            if (this.comboBox1.Text != "選擇網絡卡")
            {
                if (this.button1.Text == "開始")
                {
                    this.button1.Text = "結束";
                    this.dev = devices[this.comboBox1.SelectedIndex];
                    //if (dev == null)
                    //{
                    //    MessageBox.Show("Please choose an interface first!");
                    //}
                    //else
                    //{
                        StartCapture(dev);
                    //}
                }
                else
                {
                    //backgroundThread.Abort();
                    this.button1.Text = "開始";
                    dev.StopCapture();
                    dev.Close();
                }
            }
            else
            {
                MessageBox.Show("Please choose an interface first!");
            }
        }

        private void StartCapture(ICaptureDevice dev)
        {
            BackgroundThreadStop = false;
            backgroundThread = new System.Threading.Thread(BackgroundThread);
            backgroundThread.Start();
            arrivalEventHandler = new PacketArrivalEventHandler(device_OnPacketArrival);
            dev.OnPacketArrival += arrivalEventHandler;
            dev.Open(this.mode);
            //dev.Filter = this.filter;
            captureStatistics = dev.Statistics;
            dev.StartCapture();
        }

        public delegate void onPacketArrival(object sender, CaptureEventArgs e);
        private void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
          
            var Now = DateTime.Now; // cache 'DateTime.Now' for minor reduction in cpu overhead
            var interval = Now - LastStatisticsOutput;
            if (interval > LastStatisticsInterval)
            {
                captureStatistics = e.Device.Statistics;
                statisticsUiNeedsUpdate = true;
                LastStatisticsOutput = Now;
            }
            lock (QueueLock)
            {
                PacketQueue.Add(e.Packet);
            }
        }

        private void saveStripBtn_Click(object sender, EventArgs e)
        {
            string path = "";
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.InitialDirectory = "c:\\";
            saveFileDialog.Filter = " pcap files(*.pcap)|*.pcap";
            saveFileDialog.FilterIndex = 2;
            saveFileDialog.RestoreDirectory = true;
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                path = saveFileDialog.FileName.ToString();
            }
            if (path != "")
            {
                SharpPcap.LibPcap.CaptureFileWriterDevice captureFileWriter = new SharpPcap.LibPcap.CaptureFileWriterDevice(path, System.IO.FileMode.OpenOrCreate);

                foreach (PacketWrapper pw in this.myPackets)
                {
                    captureFileWriter.Write(pw.p);
                }
                MessageBox.Show("completed!");
            }
        }

        private void loadBtn_Click(object sender, EventArgs e)
        {
            string fileName = "";
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.InitialDirectory = "c:\\ ";
            openFileDialog.Filter = "pcap files(*.pcap)|*.pcap";
            openFileDialog.RestoreDirectory = true;
            openFileDialog.FilterIndex = 1;
            this.listView1.Items.Clear();
            number = 0;
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                fileName = openFileDialog.FileName;
            }

            if (fileName != "")
            {
                ICaptureDevice captureDevice = new SharpPcap.LibPcap.CaptureFileReaderDevice(fileName);
                int packetread = 0;
                Queue<PacketWrapper> loaded = new Queue<PacketWrapper>();
                PacketWrapper packetWrapper = null;
                captureDevice.Open();
                RawCapture rawCapture = null;
                do
                {
                    rawCapture = captureDevice.GetNextPacket();
                    packetread++;
                    if (rawCapture != null)
                    {
                        packetWrapper = new PacketWrapper(packetread, rawCapture);
                        ListViewItem aItem = new ListViewItem(packetWrapper.No.ToString());
                        aItem.SubItems.Add(packetWrapper.Protocol);
                        aItem.SubItems.Add(packetWrapper.Length);
                        aItem.SubItems.Add(packetWrapper.SourceA);
                        aItem.SubItems.Add(packetWrapper.Sourse);
                        aItem.SubItems.Add(packetWrapper.SourceP);
                        aItem.SubItems.Add(packetWrapper.DestionA);
                        aItem.SubItems.Add(packetWrapper.Destination);
                        aItem.SubItems.Add(packetWrapper.destionP);
                        aItem.SubItems.Add(packetWrapper.Time);
                        this.listView1.Items.Add(aItem);
                        myPackets.Enqueue(packetWrapper);
                    }

                } while (rawCapture != null);
                MessageBox.Show(packetread.ToString() + "packets loaded from file!");
            }
        }

        private void listView1_ItemActivate(object sender, EventArgs e)
        {
           
            foreach (PacketWrapper pw in this.myPackets)
            {
                if (pw.No.ToString() == this.listView1.SelectedItems[0].Text)
                {
                    var packet = Packet.ParsePacket(pw.p.LinkLayerType, pw.p.Data);
                    this.tbShowData.Text = packet.PrintHex();
                    this.treeView.Nodes.Clear();
                    changeTreeview(pw);
                }
            }
        }

        private void Shutdown()
        {
            if (dev != null)
            {
                dev.StopCapture();
                dev.Close();
                dev.OnPacketArrival -= arrivalEventHandler;
                dev = null;
                BackgroundThreadStop = true;
            }
        }

        private void Sniffers_FormClosing(object sender, FormClosingEventArgs e)
        {
            Shutdown();
        }    

        private void changeTreeview(PacketWrapper packet)
        {
            PacketProcesser processor = new PacketProcesser(packet);

            //frame part
            int len = processor.totalLength;
            string proto = "";
            string data = "";
            List<TreeNode> tn = new List<TreeNode>();
            foreach (string s in processor.protocols)
            {
                proto += ":" + s;
            }
            var rootStr = "Frame " + processor.num.ToString() + " " + len.ToString() + "bytes on wire(" + (len * 8).ToString() + " bits), " + len.ToString() + "bytes captured (" + (len * 8).ToString() + "bits)";
            TreeNode frameNode = new TreeNode(rootStr);
            tn.Add(new TreeNode("Arrival Time :" + processor.arrvialTime));
            tn.Add(new TreeNode("Epoch Time :" + processor.epochTime));
            tn.Add(new TreeNode("Frame Number :" + processor.num.ToString()));
            tn.Add(new TreeNode("Frame Length :" + len.ToString() + "bytes(" + (len * 8).ToString() + "bits)"));
            tn.Add(new TreeNode("Capture Length :" + len.ToString() + "bytes(" + (len * 8).ToString() + "bits)"));
            tn.Add(new TreeNode("[Protocols in frame" + proto + "]"));

            this.treeView.Nodes.Add(frameNode);
            foreach (TreeNode t in tn)
            {
                frameNode.Nodes.Add(t);
            }

            //ethernet part
            rootStr = "Ethernet II ,Src:" + processor.etherPacket.sourceHwAddress + ",Dst:" + processor.etherPacket.destinHwAddress;
            TreeNode etherNode = new TreeNode(rootStr);
            etherNode.Nodes.Add(new TreeNode("Destination :" + processor.etherPacket.destinHwAddress));
            etherNode.Nodes.Add(new TreeNode("Source :" + processor.etherPacket.sourceHwAddress));
            this.treeView.Nodes.Add(etherNode);

            //ip part
            tn = new List<TreeNode>();

            if (processor.ipPacket != null)
            {
                MyIpPacket myippack = processor.ipPacket;
                rootStr = "Internet Protocol,Src :" + myippack.sourceIpAddress + ",Dst:" + myippack.destinIpAddress;
                TreeNode ipNode = new TreeNode(rootStr);
                tn.Add(new TreeNode("Version :" + myippack.ipProtoVersion));
                tn.Add(new TreeNode("Header Length :" + myippack.ipHeaderLen));
                tn.Add(new TreeNode("Total Length :" + myippack.totalDataLen));
                tn.Add(new TreeNode("Time To Live :" + myippack.ttl));
                tn.Add(new TreeNode("Protocol :" + myippack.protocol));
                tn.Add(new TreeNode("Source :" + myippack.sourceIpAddress));
                tn.Add(new TreeNode("Destination :" + myippack.destinIpAddress));
                this.treeView.Nodes.Add(ipNode);
                foreach (TreeNode t in tn)
                {
                    ipNode.Nodes.Add(t);
                }
                data = myippack.data;
            }

            if (processor.udpPacket != null)
            {
                rootStr = "User Datagram Protocol, Src Port: " + processor.udpPacket.sourcePort + ",Dst Port: " + processor.udpPacket.destinPort;
                TreeNode upack = new TreeNode(rootStr);
                upack.Nodes.Add(new TreeNode("Source Port:" + processor.udpPacket.sourcePort));
                upack.Nodes.Add(new TreeNode("Destination Port:" + processor.udpPacket.destinPort));
                data = processor.udpPacket.data;
                this.treeView.Nodes.Add(upack);
            }
            else if (processor.tcpPacket != null)
            {
                MyTCPPacket tcppacket = processor.tcpPacket;
                byte b = processor.tcpPacket.flags;
                string fin = ".... ..." + ((b & 128) == 128 ? 1 : 0).ToString();
                string syn = ".... .." + ((b & 64) == 64 ? 1 : 0).ToString() + ".";
                string rst = ".... ." + ((b & 32) == 32 ? 1 : 0).ToString() + "..";
                string psh = ".... " + ((b & 16) == 16 ? 1 : 0).ToString() + "...";
                string ack = "..." + ((b & 8) == 8 ? 1 : 0).ToString() + " ....";
                string urg = ".." + ((b & 4) == 4 ? 1 : 0).ToString() + ". ....";
                string ecn = "." + ((b & 2) == 2 ? 1 : 0).ToString() + ".. ....";
                string cwr = ((b & 1) == 1 ? 1 : 0).ToString() + "... ....";

                rootStr = "Transmission Control Protocol,Src Port:" + tcppacket.sourcePort + ",Dst Port:" + tcppacket.destinPort + ",Seq:" + tcppacket.sequence + ",Ack:" + tcppacket.ack;
                TreeNode ipack = new TreeNode(rootStr);
                ipack.Nodes.Add(new TreeNode("Source Port:" + tcppacket.sourcePort));
                ipack.Nodes.Add(new TreeNode("Destination Port:" + tcppacket.destinPort));
                ipack.Nodes.Add(new TreeNode("Sequence Number:" + tcppacket.sequence));
                ipack.Nodes.Add(new TreeNode("Ack Number:" + tcppacket.ack));
                ipack.Nodes.Add(new TreeNode("Header Length:" + tcppacket.headerLen));
                ipack.Nodes.Add(new TreeNode("Destination Port:" + tcppacket.destinPort));
                TreeNode sub1 = new TreeNode("Flags");
                sub1.Nodes.Add("Congestion Window Reduced(CWR) = " + cwr);
                sub1.Nodes.Add("ECN-ECHO = " + ecn);
                sub1.Nodes.Add("URG = " + urg);
                sub1.Nodes.Add("ACK = " + ack);
                sub1.Nodes.Add("PUSH = " + psh);
                sub1.Nodes.Add("RESET = " + rst);
                sub1.Nodes.Add("SYN = " + syn);
                sub1.Nodes.Add("FIN = " + fin);
                ipack.Nodes.Add(sub1);
                ipack.Nodes.Add(new TreeNode("Window Size:" + tcppacket.windowSize));
                this.treeView.Nodes.Add(ipack);
                data = tcppacket.data;
            }
            if (data.Length != 0)
            {
                TreeNode da = new TreeNode("Data:" + data);
                this.treeView.Nodes.Add(da);
            }
        }

        public class MyEthernetPacket
        {
            public PacketDotNet.EthernetPacket epacket;
            public string sourceHwAddress;
            public string destinHwAddress;
            public string ethProto;
            public MyEthernetPacket(PacketDotNet.EthernetPacket packet)
            {
                this.epacket = packet;
                this.sourceHwAddress = epacket.SourceHwAddress.ToString();
                this.destinHwAddress = epacket.DestinationHwAddress.ToString();
                this.ethProto = epacket.Type.ToString();
            }
        }

        public class MyIpPacket
        {
            public PacketDotNet.IpPacket iPack;
            public string sourceIpAddress;
            public string destinIpAddress;
            public string ipProtoVersion;
            public string ipHeaderLen;
            public string totalDataLen;
            public string ttl;
            public string protocol;
            public string data;

            public MyIpPacket(PacketDotNet.IpPacket ipPacket)
            {
                this.iPack = ipPacket;
                this.sourceIpAddress = iPack.SourceAddress.ToString();
                this.destinIpAddress = iPack.DestinationAddress.ToString();
                this.ipProtoVersion = iPack.Version.ToString();
                this.ipHeaderLen = (iPack.HeaderLength * 4).ToString();
                this.totalDataLen = iPack.TotalLength.ToString();
                this.ttl = iPack.TimeToLive.ToString();
                this.protocol = iPack.Protocol.ToString();
                this.data = this.data = byteToHexStr(iPack.PayloadData);
            }

            public static string byteToHexStr(byte[] bytes)
            {
                string returnStr = "";
                if (bytes != null)
                {
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        returnStr += bytes[i].ToString("X2") + " ";
                    }
                }
                return returnStr;
            }
        }

        public class MyUDPPacket
        {
            public PacketDotNet.UdpPacket uPack;
            public string sourcePort;
            public string destinPort;
            public string len;
            public string data;

            public MyUDPPacket(PacketDotNet.UdpPacket udpPacket)
            {
                this.uPack = udpPacket;
                this.sourcePort = uPack.SourcePort.ToString();
                this.destinPort = uPack.DestinationPort.ToString();
                this.len = uPack.Bytes.Length.ToString();
                this.data = byteToHexStr(uPack.PayloadData);
            }

            public static string byteToHexStr(byte[] bytes)
            {
                string returnStr = "";
                if (bytes != null)
                {
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        returnStr += bytes[i].ToString("X2") + " ";
                    }
                }
                return returnStr;
            }
        }

        public class MyTCPPacket
        {
            public PacketDotNet.TcpPacket tpPack;
            public string sourcePort;
            public string destinPort;
            public string len;
            public string sequence;
            public string ack;
            public string headerLen;
            public byte flags;
            public string windowSize;
            public string checkSum;
            public string data;

            public MyTCPPacket(PacketDotNet.TcpPacket tcpPacket)
            {
                this.tpPack = tcpPacket;
                this.sourcePort = tpPack.SourcePort.ToString();
                this.destinPort = tpPack.DestinationPort.ToString();
                this.len = tpPack.Bytes.Length.ToString();
                this.sequence = tpPack.SequenceNumber.ToString();
                this.ack = tpPack.AcknowledgmentNumber.ToString();
                this.headerLen = tpPack.Header.Length.ToString();
                this.flags = tpPack.AllFlags;
                this.windowSize = tpPack.WindowSize.ToString();
                this.checkSum = tpPack.Checksum.ToString();
                this.data = byteToHexStr(tpPack.PayloadData);
            }

            public static string byteToHexStr(byte[] bytes)
            {
                string returnStr = "";
                if (bytes != null)
                {
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        returnStr += bytes[i].ToString("X2") + " ";
                    }
                }
                return returnStr;
            }
        }

        private void Statistics()
        {
            //Queue<PacketWrapper> myque = new Queue<PacketWrapper>();
            //foreach (PacketWrapper pw in this.myPackets)
            //{
                this.label12.Text = "總數:" + TotalCount.ToString();
                this.label13.Text = "TCP:" + TCPCount.ToString();
                this.label14.Text = "UDP:" + UDPCount.ToString();
                this.label15.Text = "ICMP:" + ICMPCount.ToString();
                this.label16.Text = "IGMP:" + IGMPCount.ToString();
                this.label17.Text = "IP:" + IPCount.ToString();
                this.label18.Text = "ARP:" + ARPCount.ToString();
                if (TotalCount == 0)
                {
                    TotalCount = 1;
                }
                this.label19.Text = "Ethernet:" + EthernetCount.ToString();
                this.progressBar1.Value = TCPCount * 100 / TotalCount;
                this.label20.Text = this.progressBar1.Value.ToString() + "%";
                this.progressBar2.Value = UDPCount * 100 / TotalCount;
                this.label21.Text = this.progressBar2.Value.ToString() + "%";
                this.progressBar3.Value = ICMPCount * 100 / TotalCount;
                this.label22.Text = this.progressBar3.Value.ToString() + "%";
                this.progressBar4.Value = IGMPCount * 100 / TotalCount;
                this.label23.Text = this.progressBar4.Value.ToString() + "%";
                this.progressBar5.Value = IPCount * 100 / TotalCount;
                this.label24.Text = this.progressBar5.Value.ToString() + "%";
                this.progressBar6.Value = ARPCount * 100 / TotalCount;
                this.label25.Text = this.progressBar6.Value.ToString() + "%";
                this.progressBar7.Value = EthernetCount * 100 / TotalCount;
                this.label26.Text = this.progressBar7.Value.ToString() + "%";
            //}
        }

        private void button2_Click(object sender, EventArgs e)
        {
            TotalCount = 0;
            TCPCount = 0;
            UDPCount = 0;
            ICMPCount = 0;
            IGMPCount = 0;
            EthernetCount = 0;
            IPCount = 0;
            ARPCount = 0;
            this.listView1.Items.Clear();
            this.Statistics();
            number = 0;
        }
    }
}