/// <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"); } }
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; }
public void Close() { if (Handle != IntPtr.Zero) { if (!WinDivertNative.WinDivertClose(Handle)) { ThrowLastWin32Error("Failed to close device"); } Handle = IntPtr.Zero; } }
public ulong GetParam(WinDivertParam param) { ThrowIfNotOpen(); var ret = WinDivertNative.WinDivertGetParam(Handle, param, out ulong value); if (!ret) { ThrowLastWin32Error("Failed to get param"); } return(value); }
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); } }
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"); } }
/// <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); } }
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); } }
/// <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); } }