Esempio n. 1
0
        /// <summary>
        /// Pcap_loop callback method.
        /// </summary>
        protected virtual void PacketHandler(IntPtr param, IntPtr /* pcap_pkthdr* */ header, IntPtr data)
        {
            var handle = Handle;
            var gotRef = false;

            try
            {
                // Make sure that handle does not get closed until this function is done
                // See https://github.com/chmorgan/sharppcap/issues/343
                handle.DangerousAddRef(ref gotRef);
                if (!gotRef)
                {
                    return;
                }
                unsafe
                {
                    var pcapHeader = PcapHeader.FromPointer(header);
                    var dataSpan   = new Span <byte>(data.ToPointer(), (int)pcapHeader.CaptureLength);
                    SendPacketArrivalEvent(pcapHeader, dataSpan);
                }
            }
            catch (ObjectDisposedException)
            {
                // If Dispose was called in another thread, DangerousAddRef will throw this
                // Ignore
            }
            finally
            {
                if (gotRef)
                {
                    handle.DangerousRelease();
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Pcap_loop callback method.
        /// </summary>
        protected virtual void PacketHandler(IntPtr param, IntPtr /* pcap_pkthdr* */ header, IntPtr data)
        {
            unsafe
            {
                var pcapHeader = PcapHeader.FromPointer(header);
                var dataSpan   = new Span <byte>(data.ToPointer(), (int)pcapHeader.CaptureLength);

                SendPacketArrivalEvent(pcapHeader, dataSpan);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Convert an unmanaged packet into a managed PacketDotNet.RawPacket
        /// </summary>
        /// <param name="header">
        /// A <see cref="IntPtr"/>
        /// </param>
        /// <param name="data">
        /// A <see cref="IntPtr"/>
        /// </param>
        /// <returns>
        /// A <see cref="RawCapture"/>
        /// </returns>
        protected virtual RawCapture MarshalRawPacket(IntPtr /* pcap_pkthdr* */ header, IntPtr data)
        {
            // marshal the header
            PcapHeader pcapHeader = PcapHeader.FromPointer(header);

            byte[] pkt_data = new byte[pcapHeader.CaptureLength];
            Marshal.Copy(data, pkt_data, 0, (int)pcapHeader.CaptureLength);

            return(new RawCapture(LinkType, new PosixTimeval(pcapHeader.Seconds, pcapHeader.MicroSeconds), pkt_data));
        }
Esempio n. 4
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);
        }
Esempio n. 5
0
        /// <summary>
        /// Convert an unmanaged packet into a managed PacketDotNet.RawPacket
        /// </summary>
        /// <param name="header">
        /// A <see cref="IntPtr"/>
        /// </param>
        /// <param name="data">
        /// A <see cref="IntPtr"/>
        /// </param>
        /// <returns>
        /// A <see cref="RawCapture"/>
        /// </returns>
        protected virtual RawCapture MarshalRawPacket(IntPtr /* pcap_pkthdr* */ header, IntPtr data)
        {
            RawCapture p;

            // marshal the header
            var pcapHeader = PcapHeader.FromPointer(header, TimestampResolution);

            var pkt_data = new byte[pcapHeader.CaptureLength];

            Marshal.Copy(data, pkt_data, 0, (int)pcapHeader.CaptureLength);

            p = new RawCapture(LinkType, pcapHeader.Timeval,
                               pkt_data, (int)pcapHeader.PacketLength);

            return(p);
        }
Esempio n. 6
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);
        }
Esempio n. 7
0
        /// <summary>
        /// Convert an unmanaged packet into a managed PacketDotNet.RawPacket
        /// </summary>
        /// <param name="header">
        /// A <see cref="IntPtr"/>
        /// </param>
        /// <param name="data">
        /// A <see cref="IntPtr"/>
        /// </param>
        /// <returns>
        /// A <see cref="RawCapture"/>
        /// </returns>
        protected virtual RawCapture MarshalRawPacket(IntPtr /* pcap_pkthdr* */ header, IntPtr data)
        {
            RawCapture p;

            // marshal the header
            var pcapHeader = PcapHeader.FromPointer(header);

            byte[] pkt_data = this.m_data_allocator != null
                ? this.m_data_allocator.Invoke(pcapHeader.CaptureLength)
                : new byte[pcapHeader.CaptureLength];

            Marshal.Copy(data, pkt_data, 0, (int)pcapHeader.CaptureLength);

            p = new RawCapture(LinkType,
                               new PosixTimeval(pcapHeader.Seconds,
                                                pcapHeader.MicroSeconds),
                               pkt_data);

            return(p);
        }