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