Exemple #1
0
        /// <summary>
        /// </summary>
        /// <param name="p"></param>
        /// <param name="header"></param>
        public void SendPacket(ReadOnlySpan <byte> p, ICaptureHeader captureHeader)
        {
            ThrowIfNotOpen();
            bool             res;
            WinDivertAddress addr = default;

            if (!(captureHeader is WinDivertHeader))
            {
                addr = GetAddress(p);
            }
            else
            {
                var header = captureHeader as WinDivertHeader;
                addr.IfIdx    = header.InterfaceIndex;
                addr.SubIfIdx = header.SubInterfaceIndex;
                addr.Flags    = header.Flags;
            }

            unsafe
            {
                fixed(byte *p_packet = p)
                {
                    res = WinDivertNative.WinDivertSend(Handle, new IntPtr(p_packet), (uint)p.Length, out var pSendLen, ref addr);
                }
            }
            if (!res)
            {
                ThrowLastWin32Error("Can't send packet");
            }
        }
Exemple #2
0
        public void SetParam(WinDivertParam param, ulong value)
        {
            ThrowIfNotOpen();
            var ret = WinDivertNative.WinDivertSetParam(Handle, param, value);

            if (!ret)
            {
                ThrowLastWin32Error("Failed to set param");
            }
        }
        public void Open()
        {
            var handle = WinDivertNative.WinDivertOpen(Filter, WinDivertLayer.Network, 0, 1);

            if (handle == IntPtr.Zero || handle == new IntPtr(-1))
            {
                ThrowLastWin32Error("Failed to open");
            }
            Handle = handle;
        }
        public void Open()
        {
            var handle = WinDivertNative.WinDivertOpen(Filter, Layer, Priority, Flags);

            if (handle == IntPtr.Zero || handle == new IntPtr(-1))
            {
                ThrowLastWin32Error("Failed to open");
            }
            Handle = handle;
        }
Exemple #5
0
 public void Close()
 {
     if (Handle != IntPtr.Zero)
     {
         if (!WinDivertNative.WinDivertClose(Handle))
         {
             ThrowLastWin32Error("Failed to close device");
         }
         Handle = IntPtr.Zero;
     }
 }
Exemple #6
0
        public ulong GetParam(WinDivertParam param)
        {
            ThrowIfNotOpen();
            var ret = WinDivertNative.WinDivertGetParam(Handle, param, out ulong value);

            if (!ret)
            {
                ThrowLastWin32Error("Failed to get param");
            }
            return(value);
        }
Exemple #7
0
        public void Open(DeviceConfiguration configuration)
        {
            var handle = WinDivertNative.WinDivertOpen(Filter, Layer, Priority, Flags);

            if (handle == IntPtr.Zero || handle == new IntPtr(-1))
            {
                ThrowLastWin32Error("Failed to open");
            }
            Handle = handle;

            if (configuration.BufferSize > 0)
            {
                SetParam(WinDivertParam.QueueSize, (uint)configuration.BufferSize);
            }
        }
Exemple #8
0
        private void SendPacket(ReadOnlySpan <byte> p, WinDivertAddress addr)
        {
            ThrowIfNotOpen();
            bool res;

            unsafe
            {
                fixed(byte *p_packet = p)
                {
                    res = WinDivertNative.WinDivertSend(Handle, new IntPtr(p_packet), (uint)p.Length, out var pSendLen, ref addr);
                }
            }
            if (!res)
            {
                ThrowLastWin32Error("Can't send packet");
            }
        }
Exemple #9
0
        /// <summary>
        /// Packet data is only valid until the next call
        /// </summary>
        /// <param name="e"></param>
        /// <returns>Status of the operation</returns>
        public GetPacketStatus GetNextPacket(out PacketCapture e)
        {
            ThrowIfNotOpen();
            while (true)
            {
                bool             ret;
                WinDivertAddress addr;
                uint             readLen;
                unsafe
                {
                    fixed(byte *p = buffer)
                    {
                        ret = WinDivertNative.WinDivertRecv(Handle, new IntPtr(p), (uint)buffer.Length, out readLen, out addr);
                    }
                }
                if (!ret)
                {
                    var err = Marshal.GetLastWin32Error();
                    if (err == ERROR_INSUFFICIENT_BUFFER)
                    {
                        // Increase buffer size
                        buffer = new byte[buffer.Length * 2];
                        continue;
                    }
                    if (err == ERROR_NO_DATA)
                    {
                        e = default;
                        return((GetPacketStatus)(-err));
                    }
                    ThrowWin32Error("Recv failed", err);
                }
                var timestamp = new PosixTimeval(BootTime + TimeSpan.FromTicks(addr.Timestamp));
                var data      = new ReadOnlySpan <byte>(buffer, 0, (int)readLen);
                var header    = new WinDivertHeader(timestamp)
                {
                    InterfaceIndex    = addr.IfIdx,
                    SubInterfaceIndex = addr.SubIfIdx,
                    Flags             = addr.Flags
                };

                e = new PacketCapture(this, header, data);

                return(GetPacketStatus.PacketRead);
            }
        }
Exemple #10
0
        public RawCapture GetNextPacket()
        {
            ThrowIfNotOpen();
            Span <byte> buffer = stackalloc byte[4096];

            while (true)
            {
                bool             ret;
                WinDivertAddress addr;
                uint             readLen;
                unsafe
                {
                    fixed(byte *p = buffer)
                    {
                        ret = WinDivertNative.WinDivertRecv(Handle, new IntPtr(p), (uint)buffer.Length, out readLen, out addr);
                    }
                }
                if (!ret)
                {
                    var err = Marshal.GetLastWin32Error();
                    if (err == ERROR_INSUFFICIENT_BUFFER)
                    {
                        // Increase buffer size
                        buffer = stackalloc byte[buffer.Length * 2];
                        continue;
                    }
                    if (err == ERROR_NO_DATA)
                    {
                        return(null);
                    }
                    ThrowWin32Error("Recv failed", err);
                }
                var timestamp = new PosixTimeval(BootTime + TimeSpan.FromTicks(addr.Timestamp));
                var data      = buffer.Slice(0, (int)readLen).ToArray();
                var raw       = new WinDivertCapture(timestamp, data)
                {
                    InterfaceIndex    = addr.IfIdx,
                    SubInterfaceIndex = addr.SubIfIdx,
                    Flags             = addr.Flags,
                };
                return(raw);
            }
        }
Exemple #11
0
        /// <summary>
        /// Packet data is only valid until the next call
        /// </summary>
        /// <param name="packets"></param>
        /// <returns>Status of the operation</returns>
        private GetPacketStatus GetNextPackets(List <PacketRecord> packets, int maxBatchSize)
        {
            ThrowIfNotOpen();
            while (true)
            {
                bool ret;
                var  addressSize       = Marshal.SizeOf <WinDivertAddress>();
                var  addressesByteSize = maxBatchSize * addressSize;
                var  addresses         = new WinDivertAddress[maxBatchSize];
                var  packetsData       = new Memory <byte>(Buffer);
                ret = WinDivertNative.WinDivertRecvEx(
                    Handle,
                    ref MemoryMarshal.GetReference(packetsData.Span),
                    packetsData.Length,
                    out int readLen,
                    0,
                    addresses,
                    ref addressesByteSize,
                    IntPtr.Zero
                    );
                if (!ret)
                {
                    var err = Marshal.GetLastWin32Error();
                    if (err == ERROR_INSUFFICIENT_BUFFER)
                    {
                        // Increase buffer size
                        Buffer = new byte[Buffer.Length * 2];
                        continue;
                    }
                    if (err == ERROR_NO_DATA)
                    {
                        return((GetPacketStatus)(-err));
                    }
                    ThrowWin32Error("Recv failed", err);
                }

                // Take only as many bytes as were written by the driver
                packetsData = packetsData.Slice(0, readLen);

                var addressesCount = addressesByteSize / addressSize;


                for (int i = 0; i < addressesCount - 1; i++)
                {
                    // We know how many packets we have, but not where they start/end in the buffer
                    // Helper function that's originally used for parsing,
                    // but we only need it to know the size of the current packet
                    var retval = WinDivertNative.WinDivertHelperParsePacket(
                        ref MemoryMarshal.GetReference(packetsData.Span),
                        packetsData.Length,
                        IntPtr.Zero, IntPtr.Zero,
                        IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
                        IntPtr.Zero, IntPtr.Zero,
                        IntPtr.Zero, out var pNextLen
                        );

                    if (!retval)
                    {
                        return(GetPacketStatus.Error);
                    }

                    var packetLength = packetsData.Length - pNextLen;

                    packets.Add(new PacketRecord(addresses[i], packetsData.Slice(0, packetLength)));

                    // Move packetsData to the next packet
                    packetsData = packetsData.Slice(packetLength);
                }

                // Avoid parsing the packet if it's the last packet or the only packet
                packets.Add(new PacketRecord(addresses[addressesCount - 1], packetsData));

                return(GetPacketStatus.PacketRead);
            }
        }