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('-', ' ')); }
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(); }
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(); }
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; } }