/// <summary> /// Flushes all write buffers of the opened dump file /// </summary> /// <param name="fileName"></param> public void PcapDumpFlush() { if (PcapDumpOpened) { SharpPcap.pcap_dump_flush(m_pcapDumpHandle); } }
/// <summary> /// Gets the next packet captured on this device /// </summary> /// <param name="p">A packet reference</param> /// <returns>A reference to a packet object</returns public virtual int PcapGetNextPacket(out Packet p) { //Pointer to a packet info struct IntPtr header = IntPtr.Zero; //Pointer to a packet struct IntPtr data = IntPtr.Zero; int res = 0; //Get a packet from winpcap res = SharpPcap.pcap_next_ex(PcapHandle, ref header, ref data); p = null; if (res > 0) { //Marshal the packet if ((header != IntPtr.Zero) && (data != IntPtr.Zero)) { SharpPcap.PCAP_PKTHDR pkt_header = (SharpPcap.PCAP_PKTHDR)Marshal.PtrToStructure(header, typeof(SharpPcap.PCAP_PKTHDR)); //SharpPcap.PCAP_PKTDATA pkt_data = (SharpPcap.PCAP_PKTDATA)Marshal.PtrToStructure( data, typeof(SharpPcap.PCAP_PKTDATA) ); byte[] pkt_data = new byte[pkt_header.caplen]; Marshal.Copy(data, pkt_data, 0, pkt_header.caplen); p = Packets.PacketFactory.dataToPacket(PcapDataLink, pkt_data, new Packets.Util.Timeval(pkt_header.tv_sec, pkt_header.tv_usec)); p.PcapHeader = new PcapHeader(pkt_header); } } return(res); }
/// <summary> /// Sends a raw packet throgh this device /// </summary> /// <param name="p">The packet bytes to send</param> /// <param name="size">The number of bytes to send</param> public void PcapSendPacket(byte[] p, int size) { if (PcapOpened) { if (size > p.Length) { throw new ArgumentException("Invalid packetSize value: " + size + "\nArgument size is larger than the total size of the packet."); } if (p.Length > SharpPcap.MAX_PACKET_SIZE) { throw new ArgumentException("Packet length can't be larger than " + SharpPcap.MAX_PACKET_SIZE); } IntPtr p_packet = IntPtr.Zero; p_packet = Marshal.AllocHGlobal(size); Marshal.Copy(p, 0, p_packet, size); int res = SharpPcap.pcap_sendpacket(PcapHandle, p_packet, size); Marshal.FreeHGlobal(p_packet); if (res < 0) { throw new PcapException("Can't send packet: " + PcapLastError); } } else { throw new PcapException("Can't send packet, the device is closed"); } }
/// <summary> /// Open the device. To start capturing call the 'PcapStartCapture' function /// </summary> /// <param name="promiscuous_mode">A value indicating wether to open the /// device in promiscuous mode (true = capture *all* packets on the network, /// including packets not for me)</param> /// <param name="read_timeout">The timeout in miliseconds to wait for a packet arrival</param> public virtual void PcapOpen(bool promiscuous_mode, int read_timeout) { short mode = 0; if (promiscuous_mode) { mode = 1; } if (!PcapOpened) { StringBuilder errbuf = new StringBuilder(SharpPcap.PCAP_ERRBUF_SIZE); //will hold errors PcapHandle = SharpPcap.pcap_open_live (PcapName, // name of the device SharpPcap.MAX_PACKET_SIZE, // portion of the packet to capture. // MAX_PACKET_SIZE (65536) grants that the whole packet will be captured on all the MACs. mode, // promiscuous mode (short)read_timeout, // read timeout errbuf); // error buffer if (PcapHandle == IntPtr.Zero) { string err = "Unable to open the adapter (" + PcapName + "). " + errbuf.ToString(); throw new Exception(err); } } }
// /// <summary> // /// This method blocks until the capturing process is stopped // /// </summary> // public virtual void WaitForStop() // { // if (PcapStarted) // { // m_pcapThreadEvent.Reset(); // m_pcapThreadEvent.WaitOne(); // } // } /// <summary> /// Closes this adapter /// </summary> public virtual void PcapClose() { if (PcapHandle == IntPtr.Zero) { return; } if (PcapStarted) { PcapStopCapture(); } SharpPcap.pcap_close(PcapHandle); PcapHandle = IntPtr.Zero; //Remove event handlers if (PcapOnPacketArrival != null) { foreach (SharpPcap.PacketArrivalEvent pa in PcapOnPacketArrival.GetInvocationList()) { PcapOnPacketArrival -= pa; } } if (PcapOnPcapStatistics != null) { foreach (SharpPcap.PcapStatisticsEvent pse in PcapOnPcapStatistics.GetInvocationList()) { PcapOnPcapStatistics -= pse; } } }
/// <summary> /// Add a packet to this send queue. /// </summary> /// <param name="packet">The packet bytes to add</param> /// <param name="pcapHdr">The pcap header of the packet</param> /// <returns>True if success, else false</returns> public bool Add(byte[] packet, SharpPcap.PCAP_PKTHDR pcapHdr) { if (m_queue == IntPtr.Zero) { throw new PcapException("Can't add packet, this queue is disposed"); } if (pcapHdr.caplen == 0) { pcapHdr.caplen = packet.Length; //set the length in the header field } //Marshal packet IntPtr pktPtr; pktPtr = Marshal.AllocHGlobal(packet.Length); Marshal.Copy(packet, 0, pktPtr, packet.Length); //Marshal header IntPtr hdrPtr; hdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SharpPcap.PCAP_PKTHDR))); Marshal.StructureToPtr(pcapHdr, hdrPtr, true); int res = SharpPcap.pcap_sendqueue_queue(m_queue, hdrPtr, pktPtr); Marshal.FreeHGlobal(pktPtr); Marshal.FreeHGlobal(hdrPtr); return(res != -1); }
/// <summary> /// Destroy the send queue. /// </summary> public void Dispose() { if (m_queue != IntPtr.Zero) { SharpPcap.pcap_sendqueue_destroy(m_queue); } }
/// <summary> /// Writes a packet to the pcap dump file associated with this device. /// </summary> /// <param name="p">The packet to write</param> public void PcapDump(byte[] p, PcapHeader h) { if (!PcapOpened) { throw new InvalidOperationException("Cannot dump packet, device is not opened"); } if (!PcapDumpOpened) { throw new InvalidOperationException("Cannot dump packet, dump file is not opened"); } //Marshal packet IntPtr pktPtr; pktPtr = Marshal.AllocHGlobal(p.Length); Marshal.Copy(p, 0, pktPtr, p.Length); //Marshal header IntPtr hdrPtr; hdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SharpPcap.PCAP_PKTHDR))); Marshal.StructureToPtr(h.m_pcap_pkthdr, hdrPtr, true); SharpPcap.pcap_dump(m_pcapDumpHandle, hdrPtr, pktPtr); Marshal.FreeHGlobal(pktPtr); Marshal.FreeHGlobal(hdrPtr); }
/// <summary> /// Closes the opened dump file /// </summary> /// <param name="fileName"></param> public void PcapDumpClose() { if (PcapDumpOpened) { SharpPcap.pcap_dump_close(m_pcapDumpHandle); m_pcapDumpHandle = IntPtr.Zero; } }
/// <summary> /// Creates and allocates a new PcapSendQueue and /// </summary> /// <param name="memSize"> /// The maximun amount of memory (in bytes) /// to allocate for the queue</param> public PcapSendQueue(int memSize) { m_queue = SharpPcap.pcap_sendqueue_alloc(memSize); if (m_queue == IntPtr.Zero) { throw new PcapException("Error creating PcapSendQueue"); } }
/// <summary> /// Opens a file for packet writings /// </summary> /// <param name="fileName"></param> public void PcapDumpOpen(string fileName) { if (PcapDumpOpened) { throw new PcapException("A dump file is already opened"); } m_pcapDumpHandle = SharpPcap.pcap_dump_open(PcapHandle, fileName); if (!PcapDumpOpened) { throw new PcapException("Error openning dump file."); } }
/// <summary> /// Send a queue of raw packets to the network. /// </summary> /// <param name="device">The PcapDevice on which to send the queue</param> /// <param name="synchronize">determines if the send operation must be synchronized: /// if it is non-zero, the packets are sent respecting the timestamps, /// otherwise they are sent as fast as possible /// <returns></returns> public int Transmit(PcapDevice device, bool synchronize) { if (!device.PcapOpened) { throw new PcapException("Can't transmit queue, the pcap device is closed."); } if (m_queue == IntPtr.Zero) { throw new PcapException("Can't transmit queue, this queue is disposed"); } int sync = synchronize ? 1 : 0; return(SharpPcap.pcap_sendqueue_transmit(device.PcapHandle, m_queue, sync)); }
/// <summary> /// Opens the device for capture /// </summary> public override void PcapOpen() { //holds errors StringBuilder errbuf = new StringBuilder(SharpPcap.PCAP_ERRBUF_SIZE); //will hold errors //opens offline pcap file IntPtr adapterHandle = SharpPcap.pcap_open_offline(this.PcapName, errbuf); //handle error if (adapterHandle == IntPtr.Zero) { string err = "Unable to open offline adapter: " + errbuf.ToString(); throw new Exception(err); } //set the local handle this.PcapHandle = adapterHandle; }
/// <summary> /// Constructs a new PcapDevice based on a 'pcapIf' struct /// </summary> /// <param name="pcapIf">A 'pcapIf' struct representing /// the pcap device /// <summary> internal PcapDevice(SharpPcap.PCAP_IF pcapIf) { m_pcapIf = pcapIf; if (m_pcapIf.Addresses != IntPtr.Zero) { SharpPcap.PCAP_ADDR pcap_addr = SharpPcap.GetPcap_Addr(m_pcapIf.Addresses); if (pcap_addr.Addr != IntPtr.Zero) { m_ip = System.Net.IPAddress.HostToNetworkOrder(SharpPcap.GetPcapAddress(pcap_addr.Addr)); } if (pcap_addr.Netmask != IntPtr.Zero) { m_mask = System.Net.IPAddress.HostToNetworkOrder(SharpPcap.GetPcapAddress(pcap_addr.Netmask)); } } }
/// <summary> /// Compile a kernel level filtering expression, and associate the filter /// with this device. For more info on filter expression syntax, see: /// http://www.winpcap.org/docs/docs31/html/group__language.html /// </summary> /// <param name="filterExpression">The filter expression to /// compile</param> public virtual void PcapSetFilter(string filterExpression) { int res; IntPtr err_ptr; string err = ""; //pointer to a bpf_program struct IntPtr program = IntPtr.Zero; //Alocate an unmanaged buffer program = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SharpPcap.bpf_program))); //compile the expreesions res = SharpPcap.pcap_compile(PcapHandle, program, filterExpression, 1, (uint)m_mask); //watch for errors if (res < 0) { try { err_ptr = SharpPcap.pcap_geterr(PcapHandle); err = Marshal.PtrToStringAnsi(err_ptr); } catch {} err = "Can't compile filter: " + err; throw new PcapException(err); } //associate the filter with this device res = SharpPcap.pcap_setfilter(PcapHandle, program); //watch for errors if (res < 0) { try { err_ptr = SharpPcap.pcap_geterr(PcapHandle); err = Marshal.PtrToStringAnsi(err_ptr); } catch {} err = "Can't set filter.\n" + err; throw new PcapException(err); } //free allocated buffers Marshal.FreeHGlobal(program); }
/// <summary> /// Add a packet to this send queue. /// </summary> /// <param name="packet">The packet bytes to add</param> /// <param name="pcapHdr">The pcap header of the packet</param> /// <returns>True if success, else false</returns> public bool Add( byte[] packet, SharpPcap.PCAP_PKTHDR pcapHdr ) { if(m_queue==IntPtr.Zero) { throw new PcapException("Can't add packet, this queue is disposed"); } if(pcapHdr.caplen==0) pcapHdr.caplen = packet.Length;//set the length in the header field //Marshal packet IntPtr pktPtr; pktPtr = Marshal.AllocHGlobal(packet.Length); Marshal.Copy(packet, 0, pktPtr, packet.Length); //Marshal header IntPtr hdrPtr; hdrPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SharpPcap.PCAP_PKTHDR))); Marshal.StructureToPtr(pcapHdr, hdrPtr, true); int res = SharpPcap.pcap_sendqueue_queue( m_queue, hdrPtr, pktPtr); Marshal.FreeHGlobal(pktPtr); Marshal.FreeHGlobal(hdrPtr); return (res!=-1); }
/// <summary> /// Constructs a new Network Device based on a PCAP_IF struct. /// </summary> internal NetworkDevice(SharpPcap.PCAP_IF pcapIf) : base(pcapIf) { Setup(); }
/// <summary> /// Constructs a new PcapHeader /// </summary> /// <param name="m_pcap_pkthdr">The underlying PCAP_PKTHDR structure</param> public PcapHeader( SharpPcap.PCAP_PKTHDR m_pcap_pkthdr ) { this.m_pcap_pkthdr=m_pcap_pkthdr; }
/// <summary> /// Constructs a new PcapDevice based on a 'pcapIf' struct /// </summary> /// <param name="pcapIf">A 'pcapIf' struct representing /// the pcap device /// <summary> internal PcapDevice( SharpPcap.PCAP_IF pcapIf ) { m_pcapIf = pcapIf; if(m_pcapIf.Addresses!=IntPtr.Zero) { SharpPcap.PCAP_ADDR pcap_addr = SharpPcap.GetPcap_Addr( m_pcapIf.Addresses ); if(pcap_addr.Addr!=IntPtr.Zero) m_ip = System.Net.IPAddress.HostToNetworkOrder( SharpPcap.GetPcapAddress( pcap_addr.Addr ) ); if(pcap_addr.Netmask!=IntPtr.Zero) m_mask = System.Net.IPAddress.HostToNetworkOrder( SharpPcap.GetPcapAddress( pcap_addr.Netmask )); } }
/// <summary> /// Constructs a new Pcap Statistics strcuture /// </summary> /// <param name="pktHdr">Time value as PCAP_PKTHDR</param> /// <param name="pktData">Statistics values as PCAP_PKTDATA</param> internal PcapStatistics(SharpPcap.PCAP_PKTHDR pktHdr, SharpPcap.PCAP_PKTDATA pktData) { this.m_pktHdr = pktHdr; this.m_pktData = pktData.bytes; }
/// <summary> /// Constructs a new PcapDevice based on a device name /// </summary> /// <param name="name">The name of a device.<br> /// Can be either in pcap device format or windows network /// device format</param> internal PcapDevice(string name) : this(SharpPcap.GetPcapDeviceStruct(name)) { }