// https://stackoverflow.com/questions/58814332/read-raw-data-from-usbpcap-library private unsafe void process_data(thread_data data, byte[] buffer, uint read) { using (MemoryStream ms = new MemoryStream(buffer, 0, (int)read)) using (BinaryReader br = new BinaryReader(ms)) { if (data.pcapHeaderReadEver == false) { br.TryRead <pcap_hdr_t>(out pcap_hdr_t header); OnHeaderRead(header); data.pcapHeaderReadEver = true; } while (true) { if (br.TryRead <pcaprec_hdr_t>(out pcaprec_hdr_t record) == false) { break; } if (br.TryRead <USBPCAP_BUFFER_PACKET_HEADER>(out USBPCAP_BUFFER_PACKET_HEADER pcapPacket) == false) { break; } int headerSize = sizeof(USBPCAP_BUFFER_PACKET_HEADER); int packetSize = ((int)record.incl_len - headerSize); byte[] packetData = br.ReadBytes(packetSize); OnDataRead(record, pcapPacket, packetData); } } }
public unsafe IntPtr create_filter_read_handle(thread_data data) { IntPtr filter_handle = SafeMethods.CreateFile(data.device, FileAccess.FILE_GENERIC_READ | FileAccess.FILE_GENERIC_WRITE, FileShare.None, IntPtr.Zero, FileMode.Open, FileAttributes.Overlapped, IntPtr.Zero); if (filter_handle == SafeMethods.INVALID_HANDLE_VALUE) { Console.WriteLine("Couldn't open device"); return(IntPtr.Zero); } bool success = false; try { USBPCAP_IOCTL_SIZE ioctlSize = new USBPCAP_IOCTL_SIZE(); ioctlSize.size = data.snaplen; uint inBufSize = (uint)sizeof(USBPCAP_IOCTL_SIZE); USBPCAP_IOCTL_SIZE *pBuf = &ioctlSize; IntPtr inBuf = new IntPtr(pBuf); success = SafeMethods.DeviceIoControl(filter_handle, SafeMethods.IOCTL_USBPCAP_SET_SNAPLEN_SIZE, inBuf, inBufSize, IntPtr.Zero, 0, out uint bytes_ret, IntPtr.Zero); if (success == false) { Console.WriteLine($"DeviceIoControl failed (supplimentary code {bytes_ret})"); return(IntPtr.Zero); } ioctlSize.size = data.bufferlen; success = SafeMethods.DeviceIoControl(filter_handle, SafeMethods.IOCTL_USBPCAP_SETUP_BUFFER, inBuf, inBufSize, IntPtr.Zero, 0, out bytes_ret, IntPtr.Zero); if (success == false) { Console.WriteLine($"DeviceIoControl failed (supplimentary code {bytes_ret})"); return(IntPtr.Zero); } fixed(USBPCAP_ADDRESS_FILTER *pFilter = &(data.filter)) { inBufSize = (uint)sizeof(USBPCAP_ADDRESS_FILTER); inBuf = new IntPtr(pFilter); success = SafeMethods.DeviceIoControl(filter_handle, SafeMethods.IOCTL_USBPCAP_START_FILTERING, inBuf, inBufSize, IntPtr.Zero, 0, out bytes_ret, IntPtr.Zero); } if (success == false) { Console.WriteLine($"DeviceIoControl failed (supplimentary code {bytes_ret})"); return(IntPtr.Zero); } return(filter_handle); } finally { if (success == false) { SafeMethods.CloseHandle(filter_handle); } } }
public USBPcapClient(string filter, int filterDeviceId) { _filterDeviceId = filterDeviceId; _data = new thread_data(); _data.device = filter; }
void read_thread(object obj) { thread_data data = obj as thread_data; try { if (data.read_handle == IntPtr.Zero) { return; } byte[] buffer = new byte[data.bufferlen]; NativeOverlapped read_overlapped = new NativeOverlapped(); NativeOverlapped connect_overlapped = new NativeOverlapped(); uint read; using (ManualResetEvent readEvent = new ManualResetEvent(false)) using (ManualResetEvent connectEvent = new ManualResetEvent(false)) { read_overlapped.EventHandle = readEvent.SafeWaitHandle.DangerousGetHandle(); connect_overlapped.EventHandle = connectEvent.SafeWaitHandle.DangerousGetHandle(); if (SafeMethods.GetFileType(data.read_handle) == FileType.FileTypePipe) { if (SafeMethods.ConnectNamedPipe(data.read_handle, ref connect_overlapped) == false) { int err = Marshal.GetLastWin32Error(); if ((err != SafeMethods.ERROR_IO_PENDING) && (err != SafeMethods.ERROR_PIPE_CONNECTED)) { Console.WriteLine("USBPcapInitAddressFilter failed!"); return; } } } else { SafeMethods.ReadFile(data.read_handle, buffer, buffer.Length, out uint _, ref read_overlapped); } EventWaitHandle[] waits = new EventWaitHandle[] { readEvent, connectEvent }; for (; data.process == true;) { int signaled = EventWaitHandle.WaitAny(waits); switch (signaled) { case 0: // readEvent SafeMethods.GetOverlappedResult(data.read_handle, ref read_overlapped, out read, true); readEvent.Reset(); process_data(data, buffer, read); SafeMethods.ReadFile(data.read_handle, buffer, buffer.Length, out read, ref read_overlapped); break; case 1: // connectEvent connectEvent.Reset(); SafeMethods.ReadFile(data.read_handle, buffer, buffer.Length, out read, ref read_overlapped); break; } } } } catch (Exception e) { Console.WriteLine(e.ToString()); } finally { data.ExitEvent.Set(); } }