/// <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)); }
/// <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); }
/// <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); }
/// <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(); } } }
/// <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)); }
/// <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); }
/// <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)); }
/// <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)); }
/// <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); } }
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); }
/// <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); }
/// <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); }
/// <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> /// 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); }
/// <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); }
/// <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); }
/// <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); }
/// <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)); }
/// <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); }
/// <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); }
/// <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; }
/// <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); }
/// <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); }
/// <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 ); }
/// <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); }
/// <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)); }
/// <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 ); }