/// <summary> /// Retrieve the next packet data /// </summary> /// <param name="e">Structure to hold the packet data info</param> /// <returns>Status of the operation</returns> public virtual GetPacketStatus GetNextPacket(out PacketCapture e) { //Pointer to a packet info struct IntPtr header = IntPtr.Zero; //Pointer to a packet struct IntPtr data = IntPtr.Zero; // using an invalid PcapHandle can result in an unmanaged segfault // so check for that here ThrowIfNotOpen("Device must be opened via Open() prior to use"); // If a user is calling GetNextPacket() when the background capture loop // is also calling into libpcap then bad things can happen // // The bad behavior I (Chris M.) saw was that the background capture would keep running // but no more packets were captured. Took two days to debug and regular users // may hit the issue more often so check and report the issue here if (Started) { throw new InvalidOperationDuringBackgroundCaptureException("GetNextPacket() invalid during background capture"); } if (!PollFileDescriptor()) { e = default; // We checked, there is no data using poll() return(GetPacketStatus.ReadTimeout); } int res; unsafe { //Get a packet from npcap res = LibPcapSafeNativeMethods.pcap_next_ex(PcapHandle, ref header, ref data); var pcapHeader = PcapHeader.FromPointer(header); var dataSpan = new Span <byte>(data.ToPointer(), (int)pcapHeader.CaptureLength); e = new PacketCapture(this, pcapHeader, dataSpan); } return((GetPacketStatus)res); }
/// <summary> /// Gets the next packet captured on this device /// </summary> /// <param name="p"> /// A <see cref="RawCapture"/> /// </param> /// <returns> /// A <see cref="int"/> that contains the result code /// </returns> public virtual int GetNextPacket(out RawCapture p) { //Pointer to a packet info struct IntPtr header = IntPtr.Zero; //Pointer to a packet struct IntPtr data = IntPtr.Zero; int res = 0; // using an invalid PcapHandle can result in an unmanaged segfault // so check for that here ThrowIfNotOpen("Device must be opened via Open() prior to use"); // If a user is calling GetNextPacket() when the background capture loop // is also calling into libpcap then bad things can happen // // The bad behavior I (Chris M.) saw was that the background capture would keep running // but no more packets were captured. Took two days to debug and regular users // may hit the issue more often so check and report the issue here if (Started) { throw new InvalidOperationDuringBackgroundCaptureException("GetNextPacket() invalid during background capture"); } p = null; if (!PollFileDescriptor()) { // We checked, there is no data using poll() return(0); } //Get a packet from npcap res = LibPcapSafeNativeMethods.pcap_next_ex(PcapHandle, ref header, ref data); if (res > 0) { //Marshal the packet if ((header != IntPtr.Zero) && (data != IntPtr.Zero)) { p = MarshalRawPacket(header, data); } } return(res); }
/// <summary> /// Gets pointers to the next PCAP header and packet data. /// Data is only valid until next call to GetNextPacketNative. /// /// Advanced use only. Intended to allow unmanaged code to avoid the overhead of /// marshalling PcapHeader and packet contents to allocated memory. /// </summary> /// <returns> /// See https://www.tcpdump.org/manpages/pcap_next_ex.3pcap.html /// </returns> public int GetNextPacketPointers(ref IntPtr header, ref IntPtr data) { return(LibPcapSafeNativeMethods.pcap_next_ex(PcapHandle, ref header, ref data)); }