Пример #1
0
        private static void PrintPacket(IntPtr ppkt_hdr, IntPtr ppkt_data)
        {
            WinPcap.WinPcap.PCAP_PKTHDR pkt_hdr = Marshal.PtrToStructure(ppkt_hdr, typeof(WinPcap.WinPcap.PCAP_PKTHDR)) as WinPcap.WinPcap.PCAP_PKTHDR;
            byte[] byt_data = new byte[pkt_hdr.caplen];
            Marshal.Copy(ppkt_data, byt_data, 0, pkt_hdr.caplen);

            Console.WriteLine(new string('*', 50));
            Console.WriteLine("{0} - Header Pointer: {1}, Data Pointer: {2}", packets++, ppkt_hdr, ppkt_data);
            Console.WriteLine("Timestamp: {2}.{3}, Packet Size: {0}/{1} ", pkt_hdr.caplen, pkt_hdr.len, pkt_hdr.tv_sec, pkt_hdr.tv_usec);
            Console.WriteLine("{0}", BitConverter.ToString(byt_data).Replace('-', ' '));
        }
Пример #2
0
        static void Main(string[] args)
        {
            Console.WriteLine(Marshal.PtrToStringAnsi(WinPcap.WinPcap.pcap_lib_version()));

            IntPtr        palldevs = IntPtr.Zero;
            StringBuilder errBuf   = new StringBuilder(1024);

            if (-1 == WinPcap.WinPcap.pcap_findalldevs_ex(
                    WinPcap.WinPcap.PCAP_SRC_IF_STRING,
                    IntPtr.Zero, ref palldevs, errBuf))
            {
                Console.WriteLine("获取设备列表错误:{0}", errBuf);
                Console.ReadKey();
                return;
            }

            int n = 0;

            WinPcap.WinPcap.PCAP_IF alldevs = null;
            List <string>           devs    = new List <string>();

            while (IntPtr.Zero != palldevs)
            {
                alldevs = Marshal.PtrToStructure(palldevs, typeof(WinPcap.WinPcap.PCAP_IF)) as WinPcap.WinPcap.PCAP_IF;
                Console.WriteLine("{0}) {1} {2}", n, alldevs.Name, alldevs.Description);
                devs.Add(alldevs.Name);

                n++;
                palldevs = alldevs.Next;
            }

            WinPcap.WinPcap.pcap_freealldevs(palldevs);

            int choice = 0;

            Console.Write("请选择一个设备:");
            if (!int.TryParse(Console.ReadLine(), out choice) ||
                choice < 0 || choice >= n)
            {
                Console.WriteLine("请输入正确的数字!");
                Console.ReadKey();
                return;
            }

            Console.WriteLine("你选择的设备是:{0}", devs[choice]);

            IntPtr ppcap = WinPcap.WinPcap.pcap_open(
                devs[choice], WinPcap.WinPcap.PCAP_SNAPLEN,
                WinPcap.WinPcap.PCAP_OPENFLAG_PROMISCUOUS,
                1000, IntPtr.Zero, errBuf);

            if (IntPtr.Zero == ppcap)
            {
                Console.WriteLine("开启设备发生错误:{0}", errBuf);
                Console.ReadKey();
                return;
            }

            if (WinPcap.WinPcap.DLT_EN10MB != WinPcap.WinPcap.pcap_datalink(ppcap))
            {
                WinPcap.WinPcap.pcap_close(ppcap);

                Console.WriteLine("只抓取以太网数据包!");
                Console.ReadKey();
                return;
            }

            const int READ_PACKETS = 100;

            int    packets   = 0;
            IntPtr ppkt_hdr  = IntPtr.Zero;
            IntPtr ppkt_data = IntPtr.Zero;

            while (packets++ < READ_PACKETS)
            {
                int ret = WinPcap.WinPcap.pcap_next_ex(ppcap, ref ppkt_hdr, ref ppkt_data);
                switch (ret)
                {
                case -2:     // if EOF was reached reading from an offline capture
                    Console.WriteLine("EOF was reached reading from an offline capture");
                    break;

                case -1:     // if an error occurred
                    Console.WriteLine("An error occurred");
                    break;

                case 0:     // if the timeout set with pcap_open_live() has elapsed. In this case pkt_header and pkt_data don't point to a valid packet
                    Console.WriteLine("The timeout set with pcap_open_live() has elapsed.");
                    break;

                case 1:     // if the packet has been read without problems
                    WinPcap.WinPcap.PCAP_PKTHDR pkt_hdr = Marshal.PtrToStructure(ppkt_hdr, typeof(WinPcap.WinPcap.PCAP_PKTHDR)) as WinPcap.WinPcap.PCAP_PKTHDR;

                    Console.WriteLine("索引:{0} - 捕获大小:{1},包体总大小:{2}(时间戳:{3}.{4})",
                                      packets, pkt_hdr.caplen, pkt_hdr.len, pkt_hdr.tv_sec, pkt_hdr.tv_usec);

                    ProcessPacket(ppkt_data, pkt_hdr);
                    break;

                default:
                    Console.WriteLine("pcap_next_ex 返回码:{0}", ret);
                    break;
                }

                Console.WriteLine(new string('*', 100));
            }

            WinPcap.WinPcap.pcap_close(ppcap);

            Console.ReadKey();
        }
Пример #3
0
        static void Main(string[] args)
        {
            Console.WriteLine(Marshal.PtrToStringAnsi(WinPcap.WinPcap.pcap_lib_version()));

            IntPtr        palldevs = IntPtr.Zero;
            StringBuilder errBuf   = new StringBuilder(1024);

            if (-1 == WinPcap.WinPcap.pcap_findalldevs_ex(
                    WinPcap.WinPcap.PCAP_SRC_IF_STRING,
                    IntPtr.Zero, ref palldevs, errBuf))
            {
                Console.WriteLine("获取设备列表错误:{0}", errBuf);
                Console.ReadKey();
                return;
            }

            int n = 0;

            WinPcap.WinPcap.PCAP_IF alldevs = null;
            List <string>           devs    = new List <string>();

            while (IntPtr.Zero != palldevs)
            {
                alldevs = Marshal.PtrToStructure(palldevs, typeof(WinPcap.WinPcap.PCAP_IF)) as WinPcap.WinPcap.PCAP_IF;
                Console.WriteLine("{0}) {1} {2}", n, alldevs.Name, alldevs.Description);
                devs.Add(alldevs.Name);

                n++;
                palldevs = alldevs.Next;
            }

            WinPcap.WinPcap.pcap_freealldevs(palldevs);

            int choice = 0;

            Console.Write("请选择一个设备:");
            if (!int.TryParse(Console.ReadLine(), out choice) ||
                choice < 0 || choice >= n)
            {
                Console.WriteLine("请输入正确的数字!");
                Console.ReadKey();
                return;
            }

            Console.Write("请输入要发送的目标 IP 或域名:");
            string targetIP = Console.ReadLine();

            if ("" == targetIP)
            {
                Console.WriteLine("请输入正确的 IP 或域名!");
                Console.ReadKey();
                return;
            }

            int packets = 0;

            Console.Write("请输入要发送的数据包数量(1 ~ 1000000):");
            if (!int.TryParse(Console.ReadLine(), out packets) ||
                packets < 1 || packets > 1000000)
            {
                Console.WriteLine("请输入正确的数字!");
                Console.ReadKey();
                return;
            }

            int       data_size = 0;
            const int MTU       = 1500;

            Console.Write("请输入除头部外要发送的数据部分大小(1 ~ {0}):", MTU);
            if (!int.TryParse(Console.ReadLine(), out data_size) ||
                data_size < 1 || data_size > MTU)
            {
                Console.WriteLine("请输入正确的数字!");
                Console.ReadKey();
                return;
            }

            IntPtr ppcap = WinPcap.WinPcap.pcap_open(
                devs[choice], WinPcap.WinPcap.PCAP_SNAPLEN,
                WinPcap.WinPcap.PCAP_OPENFLAG_PROMISCUOUS,
                10, IntPtr.Zero, errBuf);

            if (IntPtr.Zero == ppcap)
            {
                Console.WriteLine("开启设备发生错误:{0}", errBuf);
                Console.ReadKey();
                return;
            }

            const int BUF_SIZE   = MTU * 10000;
            IntPtr    pSendQueue = WinPcap.WinPcap.pcap_sendqueue_alloc(BUF_SIZE);

            if (IntPtr.Zero == pSendQueue)
            {
                Console.WriteLine("创建数据包发送队列失败:{0}", Marshal.PtrToStringAnsi(WinPcap.WinPcap.pcap_geterr(ppcap)));
                Console.ReadKey();

                WinPcap.WinPcap.pcap_close(ppcap);
                return;
            }

            //byte[] pkt = new byte[] {
            //        0x44, 0x8A, 0x5B, 0xD3, 0x73, 0xD0, // Dst MAC
            //        0xFC, 0xAA, 0x14, 0x01, 0x00, 0x52, // Src MAC
            //        0x08, 0x00, // Ethernet type
            //        0x45, // Version/Header Length
            //        0x00, // TOS
            //        0x00, 0x3C, // Packet length
            //        0x14, 0x73, // ID
            //        0x00, 0x00, // Flags
            //        0x40, // TTL
            //        0x01, // Protocol
            //        0xE1, 0xC9, // Checksum
            //        0xC0, 0xA8, 0x01, 0x9E, // Src IP
            //        0xC0, 0xA8, 0x01, 0x96, // Dst IP
            //        0x08, // ICMP Type
            //        0x00, // ICMP Code
            //        0x4D, 0x51, // Checksum
            //        0x00, 0x01, // ID
            //        0x00, 0x0A, // Seq Num
            //        0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69 };
            //GCHandle gch_pkt = GCHandle.Alloc(pkt, GCHandleType.Pinned);

            const int IS_SYNC = 0; // 0 - FALSE, -1 - TRUE

            n = 0;
            int       bytes_sent = 0, bytes_count = 0;
            UInt16    nID       = (UInt16)Thread.CurrentThread.ManagedThreadId;
            IPAddress ipa_local = WinPcap.WinPcap.GetLocalIPAddress();

            while (n < packets)
            {
                // 以太网头部
                int e_size = Marshal.SizeOf(typeof(WinPcap.WinPcap.ETHERNET_HEADER));
                WinPcap.WinPcap.ETHERNET_HEADER e_hdr = new WinPcap.WinPcap.ETHERNET_HEADER();
                e_hdr.SetENDestinationAddress(new byte[] { 0x44, 0x8A, 0x5B, 0xD3, 0x73, 0xD0 });
                e_hdr.SetENSourceAddress(new byte[] { 0xFC, 0xAA, 0x14, 0x01, 0x00, 0x52 });
                e_hdr.SetENType(WinPcap.WinPcap.ETHERNET_IP);

                // IP 头部
                int ip_size = Marshal.SizeOf(typeof(WinPcap.WinPcap.IP_HEADER));
                WinPcap.WinPcap.IP_HEADER ip_hdr = new WinPcap.WinPcap.IP_HEADER();
                ip_hdr.SetIPVersion(4);
                ip_hdr.SetIPHeaderLength((Byte)ip_size);
                ip_hdr.SetIPTypeOfService(0);
                ip_hdr.SetIPPacketLength(0); // 注:后面记得填充
                ip_hdr.SetIPID(nID);
                ip_hdr.SetIPFlags(0);
                ip_hdr.SetIPTimeToLive(0x40);
                ip_hdr.SetIPProtocol(ProtocolType.Icmp);
                ip_hdr.SetIPSourceIP(ipa_local);
                ip_hdr.SetIPDestinationIP(targetIP);

                // ICMP 头部
                int icmp_size = Marshal.SizeOf(typeof(WinPcap.WinPcap.ICMP_HEADER));
                WinPcap.WinPcap.ICMP_HEADER icmp_hdr = new WinPcap.WinPcap.ICMP_HEADER();
                icmp_hdr.SetICMPType(0x08); // 回显请求
                icmp_hdr.SetICMPCode(0x00);
                icmp_hdr.SetICMPID(nID);
                icmp_hdr.SetICMPSequenceNumber((UInt16)n);

                // 计算 IP 校验和
                ip_hdr.SetIPPacketLength((UInt16)(ip_size + icmp_size + data_size));
                GCHandle gch_ip = GCHandle.Alloc(ip_hdr, GCHandleType.Pinned);
                ip_hdr.RecalcChecksum(gch_ip.AddrOfPinnedObject());

                byte[]   pkt     = new byte[e_size + ip_size + icmp_size + data_size];
                GCHandle gch_pkt = GCHandle.Alloc(pkt, GCHandleType.Pinned);

                // 以太网头部
                IntPtr pENHdr = Marshal.AllocCoTaskMem(e_size);
                Marshal.StructureToPtr(e_hdr, pENHdr, false);
                Marshal.Copy(pENHdr, pkt, 0, e_size);
                Marshal.FreeCoTaskMem(pENHdr);

                // IP 头部
                Marshal.Copy(gch_ip.AddrOfPinnedObject(), pkt, e_size, ip_size);

                // ICMP 头部
                GCHandle gch_icmp = GCHandle.Alloc(icmp_hdr, GCHandleType.Pinned);
                Marshal.Copy(gch_icmp.AddrOfPinnedObject(), pkt, e_size + ip_size, icmp_size);

                // 生成随机数据
                Random rnd      = new Random();
                byte[] rnd_data = new byte[data_size];
                rnd.NextBytes(rnd_data);
                rnd_data.CopyTo(pkt, e_size + ip_size + icmp_size);

                // 计算 ICMP 校验和
                icmp_hdr.RecalcChecksum(gch_pkt.AddrOfPinnedObject() + e_size + ip_size, ip_hdr);
                Marshal.Copy(gch_icmp.AddrOfPinnedObject(), pkt, e_size + ip_size, icmp_size);

                WinPcap.WinPcap.PCAP_PKTHDR pkt_hdr = new WinPcap.WinPcap.PCAP_PKTHDR();
                WinPcap.WinPcap.Unix_Timestamp(ref pkt_hdr.tv_sec, ref pkt_hdr.tv_usec);
                pkt_hdr.caplen = pkt.Length;
                pkt_hdr.len    = pkt.Length;
                bytes_count   += pkt.Length;

                if (0 == WinPcap.WinPcap.pcap_sendqueue_queue(pSendQueue, pkt_hdr, gch_pkt.AddrOfPinnedObject()))
                {
                    //Console.WriteLine("{0} 队列数据包成功!", n);
                }
                else
                {
                    //Console.WriteLine("{0} 队列数据包失败!", n);

                    int sent = WinPcap.WinPcap.pcap_sendqueue_transmit(ppcap, pSendQueue, IS_SYNC);
                    bytes_sent += sent;
                    if (bytes_sent < bytes_count)
                    {
                        Console.WriteLine("本次发送:{0:###,###},发送进度:{1:###,###}/{2:###,###}", sent, bytes_sent, bytes_count);
                    }
                    else
                    {
                        bytes_sent  = 0;
                        bytes_count = 0;
                        Console.WriteLine("发送成功!");

                        WinPcap.WinPcap.pcap_sendqueue_destroy(pSendQueue);
                        pSendQueue = WinPcap.WinPcap.pcap_sendqueue_alloc(BUF_SIZE);
                        WinPcap.WinPcap.pcap_sendqueue_queue(pSendQueue, pkt_hdr, gch_pkt.AddrOfPinnedObject());
                    }
                }

                n++;

                //Thread.Sleep(1000);
            }

            while (bytes_count > 0)
            {
                int sent = WinPcap.WinPcap.pcap_sendqueue_transmit(ppcap, pSendQueue, IS_SYNC);
                bytes_sent += sent;
                if (bytes_sent < bytes_count)
                {
                    Console.WriteLine("本次发送:{0:###,###},发送进度:{1:###,###}/{2:###,###}", sent, bytes_sent, bytes_count);
                }
                else
                {
                    bytes_sent  = 0;
                    bytes_count = 0;
                    Console.WriteLine("发送成功!");
                }
            }

            WinPcap.WinPcap.pcap_sendqueue_destroy(pSendQueue);
            WinPcap.WinPcap.pcap_close(ppcap);

            Console.WriteLine("按任意键退出...");
            Console.ReadKey();
        }
Пример #4
0
        static void ProcessPacket(IntPtr pData, WinPcap.WinPcap.PCAP_PKTHDR pkt_hdr)
        {
            WinPcap.WinPcap.ETHERNET_HEADER e_hdr = Marshal.PtrToStructure(pData, typeof(WinPcap.WinPcap.ETHERNET_HEADER)) as WinPcap.WinPcap.ETHERNET_HEADER;
            Console.WriteLine();
            Console.WriteLine("Ethernet Header:");
            Console.WriteLine("Destination Address:\t\t{0}", e_hdr.GetENDestinationAddress());
            Console.WriteLine("Source Address:\t\t\t{0}", e_hdr.GetENSourceAddress());
            Console.WriteLine("Ethernet Type:\t\t\t0x{0:X4}", e_hdr.GetENType());

            Console.WriteLine();
            int en_hdr_size = Marshal.SizeOf(typeof(WinPcap.WinPcap.ETHERNET_HEADER));

            switch (e_hdr.GetENType())
            {
            case WinPcap.WinPcap.ETHERNET_IP:
                WinPcap.WinPcap.IP_HEADER ip_hdr = Marshal.PtrToStructure(pData + en_hdr_size, typeof(WinPcap.WinPcap.IP_HEADER)) as WinPcap.WinPcap.IP_HEADER;
                Console.WriteLine("IP Header:");
                Console.WriteLine("Version:\t\t\t{0}", ip_hdr.GetIPVersion());
                Console.WriteLine("Header Length:\t\t\t{0}", ip_hdr.GetIPHeaderLength());
                Console.WriteLine("Type Of Sevice:\t\t\t{0}", ip_hdr.GetIPTypeOfService());
                Console.WriteLine("Length:\t\t\t\t{0}", ip_hdr.GetIPPacketLength());
                Console.WriteLine("ID:\t\t\t\t{0}", ip_hdr.GetIPID());
                Console.WriteLine("Flags:\t\t\t\t{0:D16}", ulong.Parse(Convert.ToString(ip_hdr.GetIPFlags(), 2)));
                Console.WriteLine("Don't Fragment:\t\t\t{0}", ip_hdr.GetIPDontFragment());
                Console.WriteLine("More Fragments:\t\t\t{0}", ip_hdr.GetIPMoreFragments());
                Console.WriteLine("Fragment Offset:\t\t{0}", ip_hdr.GetIPFragmentOffset());
                Console.WriteLine("Time To Live(TTL):\t\t{0}", ip_hdr.GetIPTimeToLive());
                Console.WriteLine("Protocol:\t\t\t{0}", ip_hdr.GetIPProtocol());
                Console.WriteLine("Checksum:\t\t\t0x{0:X4}", ip_hdr.GetIPChecksum());
                Console.WriteLine("Source IP:\t\t\t{0}", ip_hdr.GetIPSourceIP());
                Console.WriteLine("Destination IP:\t\t\t{0}", ip_hdr.GetIPDestinationIP());

                int ip_hdr_size = ip_hdr.GetIPHeaderLength();
                ip_hdr.RecalcChecksum(pData + en_hdr_size);
                ProcessIPPacket(pData + en_hdr_size + ip_hdr_size, ip_hdr);
                break;

            case WinPcap.WinPcap.ETHERNET_ARP:
            case WinPcap.WinPcap.ETHERNET_RARP:
                WinPcap.WinPcap.ARP_HEADER arp_hdr = Marshal.PtrToStructure(pData + en_hdr_size, typeof(WinPcap.WinPcap.ARP_HEADER)) as WinPcap.WinPcap.ARP_HEADER;
                Console.WriteLine("ARP Header:");
                Console.WriteLine("Format Of Hardware Address:\t0x{0:X4}", arp_hdr.GetARPHardwareAddress());
                Console.WriteLine("Format Of Protocol Address:\t0x{0:X4}", arp_hdr.GetARPProtocolAddress());
                Console.WriteLine("Length Of Hardware Address:\t{0}", arp_hdr.GetARPHardwareAddressLength());
                Console.WriteLine("Length Of Protocol Address:\t{0}", arp_hdr.GetARPProtocolAddressLength());

                UInt16 arp_op = arp_hdr.GetARPOperation();
                Console.WriteLine("ARP/RARP Operation:\t\t{0}",
                                  WinPcap.WinPcap.ARP_REQUEST == arp_op ? "ARP Request" :
                                  WinPcap.WinPcap.ARP_REPLY == arp_op ? "ARP Reply" : arp_op.ToString());

                Console.WriteLine("Sender Hardware Address:\t{0}", arp_hdr.GetARPSenderMAC());
                Console.WriteLine("Sender Protocol Address:\t{0}", arp_hdr.GetARPSenderIP());
                Console.WriteLine("Target Hardware Address:\t{0}", arp_hdr.GetARPTargetMAC());
                Console.WriteLine("Target Protocol Address:\t{0}", arp_hdr.GetARPTargetIP());
                break;

            case WinPcap.WinPcap.ETHERNET_IPv6:
                break;

            case WinPcap.WinPcap.ETHERNET_PPPoE:
                break;

            default:
                Console.WriteLine("未知的以太网数据包:0x{0:X}", e_hdr.GetENType());
                break;
            }
        }