Пример #1
0
        /// <summary>
        /// Add a packet to this send queue.
        /// </summary>
        /// <param name="packet">The packet to add</param>
        /// <param name="seconds">The 'seconds' part of the packet's timestamp</param>
        /// <param name="microseconds">The 'microseconds' part of the packet's timestamp</param>
        /// <returns>True if success, else false</returns>
        public static bool Add(this SendQueue queue, byte[] packet, int seconds, int microseconds)
        {
            var header = new PcapHeader((uint)seconds, (uint)microseconds,
                                        (uint)packet.Length, (uint)packet.Length);

            return(queue.Add(header, packet));
        }
Пример #2
0
        /// <summary>
        /// Add a packet to this send queue. The PcapHeader defines the packet length.
        /// </summary>
        /// <param name="header">The pcap header of the packet</param>
        /// <param name="packet">The packet bytes to add</param>
        /// <returns>True if success, else false</returns>
        public bool Add(PcapHeader header, byte[] packet)
        {
            if (buffer == null)
            {
                throw new ObjectDisposedException(nameof(SendQueue));
            }
            var hdrSize = PcapHeader.MemorySize;
            var pktSize = (int)header.CaptureLength;

            // the header defines the size to send
            if (pktSize > packet.Length)
            {
                var error = string.Format("pcapHdr.CaptureLength of {0} > packet.Length {1}",
                                          pktSize, packet.Length);
                throw new InvalidOperationException(error);
            }

            if (hdrSize + pktSize > buffer.Length - CurrentLength)
            {
                return(false);
            }
            //Marshal header
            IntPtr hdrPtr = header.MarshalToIntPtr();

            Marshal.Copy(hdrPtr, buffer, CurrentLength, hdrSize);
            Marshal.FreeHGlobal(hdrPtr);

            Buffer.BlockCopy(packet, 0, buffer, CurrentLength + hdrSize, pktSize);

            CurrentLength += hdrSize + pktSize;

            return(true);
        }
Пример #3
0
        /// <summary>
        /// Add a packet to this send queue. The PcapHeader defines the packet length.
        /// </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>
        internal bool AddInternal( byte[] packet, PcapHeader pcapHdr )
        {
            if(m_queue==IntPtr.Zero)
            {
                throw new PcapException("Can't add packet, this queue is disposed");
            }

            // the header defines the size to send
            if(pcapHdr.CaptureLength > packet.Length)
            {
                var error = string.Format("pcapHdr.CaptureLength of {0} > packet.Length {1}",
                                          pcapHdr.CaptureLength, packet.Length);
                throw new System.InvalidOperationException(error);
            }

            //Marshal packet
            IntPtr pktPtr;
            pktPtr = Marshal.AllocHGlobal(packet.Length);
            Marshal.Copy(packet, 0, pktPtr, packet.Length);

            //Marshal header
            IntPtr hdrPtr = pcapHdr.MarshalToIntPtr();

            int res = WinPcap.SafeNativeMethods.pcap_sendqueue_queue( m_queue, hdrPtr, pktPtr);

            Marshal.FreeHGlobal(pktPtr);
            Marshal.FreeHGlobal(hdrPtr);    
    
            return (res!=-1);
        }
Пример #4
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();
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Add a packet to this send queue.
        /// </summary>
        /// <param name="packet">The packet to add</param>
        /// <returns>True if success, else false</returns>
        public static bool Add(this SendQueue queue, RawCapture packet)
        {
            var data    = packet.Data;
            var timeval = packet.Timeval;
            var header  = new PcapHeader((uint)timeval.Seconds, (uint)timeval.MicroSeconds,
                                         (uint)data.Length, (uint)data.Length);

            return(queue.Add(header, data));
        }
Пример #6
0
        /// <summary>
        /// Writes a packet to the pcap dump file associated with this device.
        /// </summary>
        /// <param name="p">The packet to write</param>
        public void Write(RawCapture p)
        {
            var data    = p.Data;
            var timeval = p.Timeval;
            var header  = new PcapHeader((uint)timeval.Seconds, (uint)timeval.MicroSeconds,
                                         (uint)data.Length, (uint)data.Length);

            Write(data, header);
        }
Пример #7
0
        /// <summary>
        /// Add a packet to this send queue.
        /// </summary>
        /// <param name="packet">The packet bytes to add</param>
        /// <returns>True if success, else false</returns>
        public static bool Add(this SendQueue queue, byte[] packet)
        {
            var header = new PcapHeader
            {
                PacketLength  = (uint)packet.Length,
                CaptureLength = (uint)packet.Length
            };

            return(queue.Add(header, packet));
        }
Пример #8
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));
        }
Пример #9
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);
            }
        }
Пример #10
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);
        }
Пример #11
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);
        }
Пример #12
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);
        }
Пример #13
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);
        }
Пример #14
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);
        }
Пример #15
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()
            {
                CaptureLength = (uint)data.Length,
                PacketLength  = (uint)data.Length,
            };
            IntPtr hdrPtr = header.MarshalToIntPtr();
            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);
        }
Пример #16
0
        /// <summary>
        /// Writes a packet to the pcap dump file associated with this device.
        /// </summary>
        /// <param name="p">P.</param>
        /// <param name="h">The height.</param>
        public void Write(ReadOnlySpan <byte> p, ref PcapHeader h)
        {
            ThrowIfNotOpen("Cannot dump packet, device is not opened");
            if (!DumpOpened)
            {
                throw new DeviceNotReadyException("Cannot dump packet, dump file is not opened");
            }

            //Marshal header
            IntPtr hdrPtr = h.MarshalToIntPtr();

            unsafe
            {
                fixed(byte *p_packet = p)
                {
                    LibPcapSafeNativeMethods.pcap_dump(m_pcapDumpHandle, hdrPtr, new IntPtr(p_packet));
                }
            }

            Marshal.FreeHGlobal(hdrPtr);
        }
Пример #17
0
        /// <summary>
        /// Writes a packet to the pcap dump file associated with this device.
        /// </summary>
        public void Write(byte[] p, PcapHeader h)
        {
            ThrowIfNotOpen("Cannot dump packet, device is not opened");
            if (!DumpOpened)
            {
                throw new DeviceNotReadyException("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 = h.MarshalToIntPtr();

            LibPcapSafeNativeMethods.pcap_dump(m_pcapDumpHandle, hdrPtr, pktPtr);

            Marshal.FreeHGlobal(pktPtr);
            Marshal.FreeHGlobal(hdrPtr);
        }
Пример #18
0
 /// <summary>
 /// Notify the OnPacketArrival delegates about a newly captured packet
 /// </summary>
 /// <param name="header"></param>
 /// <param name="data"></param>
 protected virtual void SendPacketArrivalEvent(PcapHeader header, Span <byte> data)
 {
     OnPacketArrival?.Invoke(this, new PacketCapture(this, header, data));
 }
Пример #19
0
 /// <summary>
 /// Writes a packet to the pcap dump file associated with this device.
 /// </summary>
 /// <param name="p">The packet to write</param>
 public void Dump(RawCapture p)
 {
     var data = p.Data;
     var timeval = p.Timeval;
     var header = new PcapHeader(timeval.Seconds, timeval.MicroSeconds,
                                 (uint)data.Length, (uint)data.Length);
     Dump(data, header);
 }
Пример #20
0
        /// <summary>
        /// Writes a packet to the pcap dump file associated with this device.
        /// </summary>
        public void Dump(byte[] p, PcapHeader h)
        {
            ThrowIfNotOpen("Cannot dump packet, device is not opened");
            if(!DumpOpened)
                throw new DeviceNotReadyException("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 = h.MarshalToIntPtr();

            LibPcapSafeNativeMethods.pcap_dump(m_pcapDumpHandle, hdrPtr, pktPtr);

            Marshal.FreeHGlobal(pktPtr);
            Marshal.FreeHGlobal(hdrPtr);
        }
Пример #21
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 = new PcapHeader(header);

            var pkt_data = 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;
        }
Пример #22
0
        /// <summary>
        /// Writes a packet to the pcap dump file associated with this device.
        /// </summary>
        /// <param name="p">The packet to write</param>
        public void Write(ReadOnlySpan <byte> p)
        {
            var header = new PcapHeader(0, 0, (uint)p.Length, (uint)p.Length);

            Write(p, ref header);
        }
Пример #23
0
 /// <summary>
 /// Add a packet to this send queue. 
 /// </summary>
 /// <param name="packet">The packet to add</param>
 /// <returns>True if success, else false</returns>
 public bool Add( RawCapture packet )
 {
     var data = packet.Data;
     var timeval = packet.Timeval;
     var header = new PcapHeader((uint)timeval.Seconds, (uint)timeval.MicroSeconds,
                                 (uint)data.Length, (uint)data.Length);
     return this.AddInternal(data, header);
 }
Пример #24
0
 /// <summary>
 /// Add a packet to this send queue. 
 /// </summary>
 /// <param name="packet">The packet bytes to add</param>
 /// <returns>True if success, else false</returns>
 public bool Add( byte[] packet )
 {
     PcapHeader hdr = new PcapHeader();
     hdr.CaptureLength = (uint)packet.Length;
     return this.AddInternal( packet, hdr );
 }
Пример #25
0
 /// <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>
 internal bool Add( byte[] packet, PcapHeader pcapHdr )
 {
     return this.AddInternal( packet, pcapHdr);
 }
Пример #26
0
        /// <summary>
        /// Add a packet to this send queue.
        /// </summary>
        /// <param name="packet">The packet bytes to add</param>
        /// <returns>True if success, else false</returns>
        public static bool Add(this SendQueue queue, byte[] packet)
        {
            var header = new PcapHeader(0, 0, (uint)packet.Length, (uint)packet.Length);

            return(queue.Add(header, packet));
        }
Пример #27
0
 /// <summary>
 /// Add a packet to this send queue.
 /// </summary>
 /// <param name="packet">The packet to add</param>
 /// <param name="seconds">The 'seconds' part of the packet's timestamp</param>
 /// <param name="microseconds">The 'microseconds' part of the packet's timestamp</param>
 /// <returns>True if success, else false</returns>
 public bool Add( byte[] packet, int seconds, int microseconds )
 {
     var header = new PcapHeader((uint)seconds, (uint)microseconds,
                                 (uint)packet.Length, (uint)packet.Length);
     
     return this.Add( packet, header );
 }