예제 #1
0
        /// <summary>
        /// Open the device
        /// </summary>
        public override void Open(DeviceConfiguration configuration)
        {
            // set the device handle
            var has_open_dead_with_tstamp_precision_support = Pcap.LibpcapVersion >= new Version(1, 5, 1);
            var resolution = configuration.TimestampResolution ?? TimestampResolution.Microsecond;

            if (has_open_dead_with_tstamp_precision_support)
            {
                PcapHandle = LibPcapSafeNativeMethods.pcap_open_dead_with_tstamp_precision((int)configuration.LinkLayerType,
                                                                                           configuration.Snaplen,
                                                                                           (uint)resolution);
            }
            else
            {
                if (resolution != TimestampResolution.Microsecond)
                {
                    configuration.RaiseConfigurationFailed(
                        nameof(configuration.TimestampResolution),
                        (int)PcapError.PlatformNotSupported,
                        "pcap version is < 1.5.1, needs pcap_open_dead_with_tstamp_precision()"
                        );
                }

                PcapHandle = LibPcapSafeNativeMethods.pcap_open_dead((int)configuration.LinkLayerType, configuration.Snaplen);
            }

            m_pcapDumpHandle = LibPcapSafeNativeMethods.pcap_dump_open(PcapHandle, m_pcapFile);
            if (m_pcapDumpHandle == IntPtr.Zero)
            {
                throw new PcapException("Error opening dump file '" + LastError + "'");
            }

            Active = true;
        }
예제 #2
0
        static public IReadOnlyList <PcapInterface> GetAllPcapInterfaces(string source, RemoteAuthentication credentials)
        {
            var devicePtr   = IntPtr.Zero;
            var errorBuffer = new StringBuilder(Pcap.PCAP_ERRBUF_SIZE);
            var auth        = RemoteAuthentication.CreateAuth(credentials);

            try
            {
                var result = LibPcapSafeNativeMethods.pcap_findalldevs_ex(source, ref auth, ref devicePtr, errorBuffer);
                if (result < 0)
                {
                    throw new PcapException(errorBuffer.ToString());
                }
            }
            catch (TypeLoadException ex)
            {
                throw new PlatformNotSupportedException(
                          "Operation is not supported on this platform.",
                          ex
                          );
            }

            var pcapInterfaces = GetAllPcapInterfaces(devicePtr, credentials);

            // Free unmanaged memory allocation
            LibPcapSafeNativeMethods.pcap_freealldevs(devicePtr);

            return(pcapInterfaces);
        }
예제 #3
0
        /// <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 override void SendPacket(byte[] p, int size)
        {
            ThrowIfNotOpen("Can't send packet, the device is closed");

            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 > Pcap.MAX_PACKET_SIZE)
            {
                throw new ArgumentException("Packet length can't be larger than " + Pcap.MAX_PACKET_SIZE);
            }

            IntPtr p_packet = IntPtr.Zero;

            p_packet = Marshal.AllocHGlobal(size);
            Marshal.Copy(p, 0, p_packet, size);

            int res = LibPcapSafeNativeMethods.pcap_sendpacket(PcapHandle, p_packet, size);

            Marshal.FreeHGlobal(p_packet);
            if (res < 0)
            {
                throw new PcapException("Can't send packet: " + LastError);
            }
        }
예제 #4
0
        public static BpfProgram TryCreate(PcapHandle pcapHandle, string filter, int optimize = 1, uint netmask = 0)
        {
            var bpfProgram = new BpfProgram();
            int result;

            // Compile the expressions
            if (ThreadSafeCompile)
            {
                result = LibPcapSafeNativeMethods.pcap_compile(pcapHandle,
                                                               bpfProgram,
                                                               filter,
                                                               optimize,
                                                               netmask);
            }
            else
            {
                lock (SyncCompile)
                {
                    result = LibPcapSafeNativeMethods.pcap_compile(pcapHandle,
                                                                   bpfProgram,
                                                                   filter,
                                                                   optimize,
                                                                   netmask);
                }
            }
            if (result < 0)
            {
                // Don't use Dispose since we don't want pcap_freecode to be called here
                Marshal.FreeHGlobal(bpfProgram.handle);
                bpfProgram.SetHandle(IntPtr.Zero);
                bpfProgram = null;
            }
            return(bpfProgram);
        }
예제 #5
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="linkLayerType">
        /// A <see cref="PacketDotNet.LinkLayers"/>
        /// </param>
        /// <param name="snapshotLength">
        /// A <see cref="System.Nullable&lt;System.Int32&gt;"/>
        /// </param>
        /// <param name="captureFilename">
        /// A <see cref="System.String"/>
        /// </param>
        /// <param name="mode">
        /// A <see cref="FileMode"/>
        /// </param>
        public CaptureFileWriterDevice(PacketDotNet.LinkLayers linkLayerType,
                                       int?snapshotLength,
                                       string captureFilename,
                                       FileMode mode)
        {
            m_pcapFile = captureFilename;

            // append isn't possible without some difficulty and not implemented yet
            if (mode == FileMode.Append)
            {
                throw new System.InvalidOperationException("FileMode.Append is not supported, please contact the developers if you are interested in helping to implementing it");
            }

            if (!snapshotLength.HasValue)
            {
                snapshotLength = Pcap.MAX_PACKET_SIZE;
            }
            else if (snapshotLength > Pcap.MAX_PACKET_SIZE)
            {
                throw new System.InvalidOperationException("snapshotLength > Pcap.MAX_PACKET_SIZE");
            }

            // set the device handle
            PcapHandle = LibPcapSafeNativeMethods.pcap_open_dead((int)linkLayerType, snapshotLength.Value);

            m_pcapDumpHandle = LibPcapSafeNativeMethods.pcap_dump_open(PcapHandle, captureFilename);
            if (m_pcapDumpHandle == IntPtr.Zero)
            {
                throw new PcapException("Error opening dump file '" + LastError + "'");
            }
        }
예제 #6
0
        /// <summary>
        /// Assign a filter to this device given a filterExpression
        /// </summary>
        /// <param name="filterExpression">The filter expression to compile</param>
        protected void SetFilter(string filterExpression)
        {
            // save the filter string
            _filterString = filterExpression;

            int res;

            // pcap_setfilter() requires a valid pcap_t which isn't present if
            // the device hasn't been opened
            ThrowIfNotOpen("device is not open");

            // attempt to compile the program
            if (!CompileFilter(PcapHandle, filterExpression, 0, out IntPtr bpfProgram, out string errorString))
            {
                string err = string.Format("Can't compile filter ({0}) : {1} ", filterExpression, errorString);
                throw new PcapException(err);
            }

            //associate the filter with this device
            res = LibPcapSafeNativeMethods.pcap_setfilter(PcapHandle, bpfProgram);

            // Free the program whether or not we were successful in setting the filter
            // we don't want to leak unmanaged memory if we throw an exception.
            FreeBpfProgram(bpfProgram);

            //watch for errors
            if (res < 0)
            {
                errorString = string.Format("Can't set filter ({0}) : {1}", filterExpression, LastError);
                throw new PcapException(errorString);
            }
        }
예제 #7
0
 protected override bool ReleaseHandle()
 {
     LibPcapSafeNativeMethods.pcap_freecode(handle);
     //Alocate an unmanaged buffer
     Marshal.FreeHGlobal(handle);
     return(true);
 }
예제 #8
0
        /// <summary>
        /// Closes this adapter
        /// </summary>
        public virtual void Close()
        {
            if (PcapHandle == IntPtr.Zero)
            {
                return;
            }

            if (Started)
            {
                try
                {
                    StopCapture();
                }
                catch (Exception) { }
            }
            LibPcapSafeNativeMethods.pcap_close(PcapHandle);
            PcapHandle = IntPtr.Zero;

            //Remove event handlers
            if (OnPacketArrival != null)
            {
                foreach (PacketArrivalEventHandler pa in OnPacketArrival.GetInvocationList())
                {
                    OnPacketArrival -= pa;
                }
            }
        }
예제 #9
0
 public static BpfProgram Create(LinkLayers linktype, string filter, int optimize = 1, uint netmask = 0)
 {
     using (var handle = LibPcapSafeNativeMethods.pcap_open_dead((int)linktype, Pcap.MAX_PACKET_SIZE))
     {
         return(Create(handle, filter, optimize, netmask));
     }
 }
예제 #10
0
        public static bool CompileFilter(IntPtr pcapHandle,
                                         string filterExpression,
                                         uint mask,
                                         out IntPtr bpfProgram,
                                         out string errorString)
        {
            errorString = null;

            //Alocate an unmanaged buffer
            bpfProgram = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PcapUnmanagedStructures.bpf_program)));

            //compile the expressions
            var result = LibPcapSafeNativeMethods.pcap_compile(pcapHandle,
                                                               bpfProgram,
                                                               filterExpression,
                                                               1,
                                                               mask);

            if (result < 0)
            {
                var err = GetLastError(pcapHandle);

                // free up the program memory
                Marshal.FreeHGlobal(bpfProgram);
                bpfProgram = IntPtr.Zero; // make sure not to pass out a valid pointer

                // set the error string
                errorString = err;

                return(false);
            }

            return(true);
        }
        /// <summary>
        /// Retrieve a list of the current PcapDevices
        /// </summary>
        /// <returns>
        /// A <see cref="List&lt;LibPcapLiveDevice&gt;"/>
        /// </returns>
        private static List <LibPcapLiveDevice> GetDevices()
        {
            var deviceList = new List <LibPcapLiveDevice>();

            var devicePtr   = IntPtr.Zero;
            var errorBuffer = new StringBuilder(Pcap.PCAP_ERRBUF_SIZE);

            int result = LibPcapSafeNativeMethods.pcap_findalldevs(ref devicePtr, errorBuffer);

            if (result < 0)
            {
                throw new PcapException(errorBuffer.ToString());
            }

            IntPtr nextDevPtr = devicePtr;

            while (nextDevPtr != IntPtr.Zero)
            {
                // Marshal pointer into a struct
                PcapUnmanagedStructures.pcap_if pcap_if_unmanaged =
                    (PcapUnmanagedStructures.pcap_if)Marshal.PtrToStructure(nextDevPtr,
                                                                            typeof(PcapUnmanagedStructures.pcap_if));
                PcapInterface pcap_if = new PcapInterface(pcap_if_unmanaged);
                deviceList.Add(new LibPcapLiveDevice(pcap_if));
                nextDevPtr = pcap_if_unmanaged.Next;
            }
            LibPcapSafeNativeMethods.pcap_freealldevs(devicePtr);  // Free unmanaged memory allocation.

            return(deviceList);
        }
예제 #12
0
        /// <summary>
        /// Open the device. To start capturing call the 'StartCapture' function
        /// </summary>
        /// <param name="mode">
        /// A <see cref="DeviceMode"/>
        /// </param>
        /// <param name="read_timeout">
        /// A <see cref="System.Int32"/>
        /// </param>
        public override void Open(DeviceMode mode, int read_timeout)
        {
            if (!Opened)
            {
                StringBuilder errbuf = new StringBuilder(Pcap.PCAP_ERRBUF_SIZE);   //will hold errors

                // set the StopCaptureTimeout value to twice the read timeout to ensure that
                // we wait long enough before considering the capture thread to be stuck when stopping
                // a background capture via StopCapture()
                //
                // NOTE: Doesn't affect Mono if unix poll is available, doesn't affect Linux because
                //       Linux devices have no timeout, they always block. Only affects Windows devices.
                StopCaptureTimeout = new TimeSpan(0, 0, 0, 0, read_timeout * 2);

                PcapHandle = LibPcapSafeNativeMethods.pcap_open_live
                                 (Name,                // name of the device
                                 Pcap.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.
                                 (int)mode,            // promiscuous mode
                                 read_timeout,         // read timeout
                                 errbuf);              // error buffer

                if (PcapHandle == IntPtr.Zero)
                {
                    string err = "Unable to open the adapter (" + Name + "). " + errbuf.ToString();
                    throw new PcapException(err);
                }
            }
        }
예제 #13
0
        public static void FreeBpfProgram(IntPtr bpfProgram)
        {
            // free any pcap internally allocated memory from pcap_compile()
            LibPcapSafeNativeMethods.pcap_freecode(bpfProgram);

            // free allocated buffers
            Marshal.FreeHGlobal(bpfProgram);
        }
예제 #14
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="device">
        /// A <see cref="LibPcapLiveDevice"/>
        /// </param>
        /// <param name="captureFilename">
        /// A <see cref="System.String"/>
        /// </param>
        public CaptureFileWriterDevice(LibPcapLiveDevice device,
                                       string captureFilename) :
            this((PacketDotNet.LinkLayers)LibPcapSafeNativeMethods.pcap_datalink(device.PcapHandle),
                 LibPcapSafeNativeMethods.pcap_snapshot(device.PcapHandle),
                 captureFilename,
                 FileMode.OpenOrCreate)

        {
        }
예제 #15
0
 /// <summary>
 /// Stops the capture process
 ///
 /// Throws an exception if the stop capture timeout is exceeded and the
 /// capture thread was aborted
 /// </summary>
 public virtual void StopCapture()
 {
     if (Started)
     {
         threadCancellationTokenSource.Cancel();
         threadCancellationTokenSource = new CancellationTokenSource();
         LibPcapSafeNativeMethods.pcap_breakloop(Handle);
         Task.WaitAny(new[] { captureThread }, StopCaptureTimeout);
         captureThread = null;
     }
 }
예제 #16
0
        /// <summary>
        /// Open the device. To start capturing call the 'StartCapture' function
        /// </summary>
        /// <param name="mode">
        /// A <see cref="DeviceMode"/>
        /// </param>
        /// <param name="read_timeout">
        /// A <see cref="System.Int32"/>
        /// </param>
        /// <param name="monitor_mode">
        /// A <see cref="MonitorMode"/>
        /// </param>
        /// <param name="kernel_buffer_size">
        /// A <see cref="System.UInt32"/>
        /// </param>
        public override void Open(DeviceMode mode, int read_timeout, MonitorMode monitor_mode, uint kernel_buffer_size)
        {
            if (!Opened)
            {
                StringBuilder errbuf = new StringBuilder(Pcap.PCAP_ERRBUF_SIZE); //will hold errors

                // set the StopCaptureTimeout value to twice the read timeout to ensure that
                // we wait long enough before considering the capture thread to be stuck when stopping
                // a background capture via StopCapture()
                //
                // NOTE: Doesn't affect Mono if unix poll is available, doesn't affect Linux because
                //       Linux devices have no timeout, they always block. Only affects Windows devices.
                StopCaptureTimeout = new TimeSpan(0, 0, 0, 0, read_timeout * 2);

                PcapHandle = LibPcapSafeNativeMethods.pcap_create(
                    Name,    // name of the device
                    errbuf); // error buffer

                if (PcapHandle == IntPtr.Zero)
                {
                    string err = "Unable to open the adapter (" + Name + "). " + errbuf.ToString();
                    throw new PcapException(err);
                }

                LibPcapSafeNativeMethods.pcap_set_snaplen(PcapHandle, Pcap.MAX_PACKET_SIZE);
                if (monitor_mode == MonitorMode.Active)
                {
                    try
                    {
                        LibPcapSafeNativeMethods.pcap_set_rfmon(PcapHandle, (int)monitor_mode);
                    }
                    catch (System.EntryPointNotFoundException)
                    {
                        throw new PcapException("This implementation of libpcap does not support monitor mode.");
                    }
                }

                LibPcapSafeNativeMethods.pcap_set_promisc(PcapHandle, (int)mode);
                LibPcapSafeNativeMethods.pcap_set_timeout(PcapHandle, read_timeout);

                if (kernel_buffer_size != 0)
                {
                    KernelBufferSize = kernel_buffer_size;
                }

                var activationResult = LibPcapSafeNativeMethods.pcap_activate(PcapHandle);
                if (activationResult < 0)
                {
                    string err = "Unable to activate the adapter (" + Name + "). Return code: " + activationResult.ToString();
                    throw new PcapException(err);
                }
                Active = true;
            }
        }
예제 #17
0
        protected unsafe int ManagedTransmit(PcapDevice device, bool synchronized)
        {
            if (CurrentLength == 0)
            {
                return(0);
            }
            var position = 0;
            var hdrSize  = PcapHeader.MemorySize;
            var sw       = new Stopwatch();

            fixed(byte *buf = buffer)
            {
                var bufPtr         = new IntPtr(buf);
                var firstTimestamp = TimeSpan.FromTicks(PcapHeader.FromPointer(bufPtr).Date.Ticks);

                while (position < CurrentLength)
                {
                    // Extract packet from buffer
                    var header  = PcapHeader.FromPointer(bufPtr + position);
                    var pktSize = (int)header.CaptureLength;
                    var p       = new ReadOnlySpan <byte>(buffer, position + hdrSize, pktSize);
                    if (synchronized)
                    {
                        var timestamp     = TimeSpan.FromTicks(header.Date.Ticks);
                        var remainingTime = timestamp.Subtract(firstTimestamp);
                        while (sw.Elapsed < remainingTime)
                        {
                            // Wait for packet time
                            System.Threading.Thread.Sleep((int)remainingTime.TotalMilliseconds / 2);
                        }
                    }
                    // Send the packet
                    int res;
                    unsafe
                    {
                        fixed(byte *p_packet = p)
                        {
                            res = LibPcapSafeNativeMethods.pcap_sendpacket(device.PcapHandle, new IntPtr(p_packet), p.Length);
                        }
                    }
                    // Start Stopwatch after sending first packet
                    sw.Start();
                    if (res < 0)
                    {
                        break;
                    }
                    position += hdrSize + pktSize;
                }
            }

            return(position);
        }
예제 #18
0
        /// <summary>
        /// Runs the program and returns if a given filter applies to the packet
        /// </summary>
        /// <param name="bpfProgram">
        /// A <see cref="IntPtr"/>
        /// </param>
        public bool Matches(ReadOnlySpan <byte> data)
        {
            var header = new PcapHeader(0, 0, (uint)data.Length, (uint)data.Length);
            var hdrPtr = header.MarshalToIntPtr(TimestampResolution.Microsecond);
            int result;

            unsafe
            {
                fixed(byte *p_packet = data)
                {
                    result = LibPcapSafeNativeMethods.pcap_offline_filter(this, hdrPtr, new IntPtr(p_packet));
                }
            }
            Marshal.FreeHGlobal(hdrPtr);
            return(result != 0);
        }
예제 #19
0
        /// <summary>
        /// Close the capture file
        /// </summary>
        public override void Close()
        {
            if (!Opened)
            {
                return;
            }

            base.Close();

            // close the dump handle
            if (m_pcapDumpHandle != IntPtr.Zero)
            {
                LibPcapSafeNativeMethods.pcap_dump_close(m_pcapDumpHandle);
                m_pcapDumpHandle = IntPtr.Zero;
            }
        }
예제 #20
0
        protected unsafe int NativeTransmit(PcapDevice device, bool synchronized)
        {
            int sync = synchronized ? 1 : 0;

            fixed(byte *buf = buffer)
            {
                var pcap_queue = new pcap_send_queue
                {
                    maxlen  = (uint)buffer.Length,
                    len     = (uint)CurrentLength,
                    ptrBuff = new IntPtr(buf)
                };

                return(LibPcapSafeNativeMethods.pcap_sendqueue_transmit(device.PcapHandle, ref pcap_queue, sync));
            }
        }
예제 #21
0
        /// <summary>
        /// Open the device. To start capturing call the 'StartCapture' function
        /// </summary>
        /// <param name="configuration">
        /// A <see cref="DeviceConfiguration"/>
        /// </param>
        public virtual void Open(DeviceConfiguration configuration)
        {
            // Caches linkType value.
            // Open refers to the device being "created"
            // This method is called by sub-classes in the override method
            int dataLink = 0;

            if (Opened)
            {
                dataLink = LibPcapSafeNativeMethods.pcap_datalink(Handle);
            }
            if (dataLink >= 0)
            {
                linkType = (PacketDotNet.LinkLayers)dataLink;
            }
        }
예제 #22
0
        /// <summary>
        /// Sends a raw packet through this device
        /// </summary>
        /// <param name="p">The packet bytes to send</param>
        public void SendPacket(ReadOnlySpan <byte> p, ICaptureHeader header = null)
        {
            ThrowIfNotOpen("Can't send packet, the device is closed");
            int res;

            unsafe
            {
                fixed(byte *p_packet = p)
                {
                    res = LibPcapSafeNativeMethods.pcap_sendpacket(Handle, new IntPtr(p_packet), p.Length);
                }
            }
            if (res < 0)
            {
                throw new PcapException("Can't send packet: " + LastError);
            }
        }
예제 #23
0
        /// <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);
        }
예제 #24
0
 private static bool GetIsHardwareAccelerated()
 {
     using (var handle = LibPcapSafeNativeMethods.pcap_open_dead(1, 60))
     {
         try
         {
             pcap_send_queue queue = default;
             LibPcapSafeNativeMethods.pcap_sendqueue_transmit(handle, ref queue, 0);
             return(true);
         }
         catch (TypeLoadException)
         {
             // Function pcap_sendqueue_transmit not found
             return(false);
         }
     }
 }
예제 #25
0
        static public IReadOnlyList <PcapInterface> GetAllPcapInterfaces()
        {
            var devicePtr   = IntPtr.Zero;
            var errorBuffer = new StringBuilder(Pcap.PCAP_ERRBUF_SIZE);

            int result = LibPcapSafeNativeMethods.pcap_findalldevs(ref devicePtr, errorBuffer);

            if (result < 0)
            {
                throw new PcapException(errorBuffer.ToString());
            }
            var pcapInterfaces = GetAllPcapInterfaces(devicePtr, null);

            // Free unmanaged memory allocation
            LibPcapSafeNativeMethods.pcap_freealldevs(devicePtr);

            return(pcapInterfaces);
        }
예제 #26
0
        /// <summary>
        /// Returns true if the filter expression was able to be compiled into a
        /// program without errors
        /// </summary>
        public static bool CheckFilter(string filterExpression,
                                       out string errorString)
        {
            IntPtr fakePcap = LibPcapSafeNativeMethods.pcap_open_dead((int)PacketDotNet.LinkLayers.Ethernet, Pcap.MAX_PACKET_SIZE);

            uint mask = 0;

            if (!CompileFilter(fakePcap, filterExpression, mask, out IntPtr bpfProgram, out errorString))
            {
                LibPcapSafeNativeMethods.pcap_close(fakePcap);
                return(false);
            }

            FreeBpfProgram(bpfProgram);

            LibPcapSafeNativeMethods.pcap_close(fakePcap);
            return(true);
        }
예제 #27
0
        /// <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);
        }
예제 #28
0
 /// <summary>
 /// Returns true if the filter expression was able to be compiled into a
 /// program without errors
 /// </summary>
 public static bool CheckFilter(string filterExpression,
                                out string errorString)
 {
     errorString = null;
     using (var pcapHandle = LibPcapSafeNativeMethods.pcap_open_dead((int)PacketDotNet.LinkLayers.Ethernet, Pcap.MAX_PACKET_SIZE))
     {
         var bpfProgram = BpfProgram.TryCreate(pcapHandle, filterExpression);
         if (bpfProgram == null)
         {
             errorString = GetLastError(pcapHandle);
             return(false);
         }
         else
         {
             bpfProgram.Dispose();
             return(true);
         }
     }
 }
예제 #29
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="captureFilename">
        /// A <see cref="System.String"/>
        /// </param>
        public CaptureFileReaderDevice(string captureFilename)
        {
            m_pcapFile = captureFilename;

            // holds errors
            StringBuilder errbuf = new StringBuilder(Pcap.PCAP_ERRBUF_SIZE);   //will hold errors
            // opens offline pcap file
            IntPtr adapterHandle = LibPcapSafeNativeMethods.pcap_open_offline(captureFilename, errbuf);

            // handle error
            if (adapterHandle == IntPtr.Zero)
            {
                string err = "Unable to open offline adapter: " + errbuf.ToString();
                throw new PcapException(err);
            }

            // set the device handle
            PcapHandle = adapterHandle;
        }
예제 #30
0
        /// <summary>
        /// Open the device
        /// </summary>
        public override void Open(DeviceConfiguration configuration)
        {
            // holds errors
            StringBuilder errbuf = new StringBuilder(Pcap.PCAP_ERRBUF_SIZE); //will hold errors

            PcapHandle adapterHandle;

            // Check if we need to open with a defined precision
            var has_offline_with_tstamp_precision_support = Pcap.LibpcapVersion >= new Version(1, 5, 1);
            var resolution = configuration.TimestampResolution ?? TimestampResolution.Microsecond;

            if (has_offline_with_tstamp_precision_support)
            {
                adapterHandle = LibPcapSafeNativeMethods.pcap_open_offline_with_tstamp_precision(m_pcapFile, (uint)resolution, errbuf);
            }
            else
            {
                // notify the user that they asked for a non-standard resolution but their libpcap
                // version lacks the necessary function
                if (resolution != TimestampResolution.Microsecond)
                {
                    configuration.RaiseConfigurationFailed(
                        nameof(configuration.TimestampResolution),
                        (int)PcapError.PlatformNotSupported,
                        "pcap version is < 1.5.1, needs pcap_open_offline_with_tstamp_precision()"
                        );
                }

                adapterHandle = LibPcapSafeNativeMethods.pcap_open_offline(m_pcapFile, errbuf);
            }

            // handle error
            if (adapterHandle.IsInvalid)
            {
                string err = "Unable to open offline adapter: " + errbuf.ToString();
                throw new PcapException(err);
            }

            // set the device handle
            Handle = adapterHandle;

            base.Open(configuration);
        }