public int Receive(out byte[] buffer) { // retrieve data from allocated buffer. NetworkBufferFactory.Buffer data = _socketState.bufferFactory.GetNextAllocatedBuffer(); buffer = data?.Data; return(data?.AllocatedSize ?? 0); }
public void FreeBuffer(ref byte[] buffer) { NetworkBufferFactory.Buffer data = new NetworkBufferFactory.Buffer() { Data = buffer, AllocatedSize = 0 }; _socketState.bufferFactory.AddFreeBuffer(data); }
private static void OnReceive(IAsyncResult ar) { try { SocketState state = ar.AsyncState as SocketState; if (state == null) { return; } NetworkBufferFactory.Buffer buffer = state?.buffer; lock (state.socketLock) { if (state.socket == null) { return; } int received = state.socket.EndReceive(ar); state.buffer = state.bufferFactory.GetNextFreeBuffer(); state.socket.BeginReceive(state.buffer.Data, 0, state.buffer.Data.Length, SocketFlags.None, new System.AsyncCallback(OnReceive), (object)state); if (received > 0) { buffer.AllocatedSize = received; state.bufferFactory.AddAllocatedBuffer(buffer); } } } catch (ObjectDisposedException) { // do nothing - teardown occurring. } catch (Exception ex) { Trace.WriteLine("RawSocket: Error while receiving socket data. Network capture aborted, please restart application." + ex.ToString(), "DEBUG-MACHINA"); } }
private unsafe void RunCaptureLoop() { bool bExceptionLogged = false; while (_cancelThread == false) { try { if (_activeDevice == null) { Thread.Sleep(100); continue; } IntPtr packetDataPtr = IntPtr.Zero; IntPtr packetHeaderPtr = IntPtr.Zero; int layer2Length = (_activeDevice.LinkType == DLT_EN10MB ? 14 : 4); // 14 for ethernet, 4 for loopback // note: buffer returned by pcap_next_ex is static and owned by pcap library, does not need to be freed. int status = pcap_next_ex(_activeDevice.Handle, ref packetHeaderPtr, ref packetDataPtr); if (status == 0) // 500ms timeout { continue; } else if (status == -1) // error { string error = Marshal.PtrToStringAnsi(pcap_geterr(_activeDevice.Handle)); if (!bExceptionLogged) { Trace.WriteLine("RawPCap: Error during pcap_loop. " + error); } bExceptionLogged = true; Thread.Sleep(100); } else if (status != 1) // anything else besides success { if (!bExceptionLogged) { Trace.WriteLine("RawPCap: Unknown response code [" + status.ToString() + "] from pcap_next_ex.);"); } bExceptionLogged = true; Thread.Sleep(100); } else { pcap_pkthdr packetHeader = *(pcap_pkthdr *)packetHeaderPtr; if (packetHeader.caplen <= layer2Length) { continue; } NetworkBufferFactory.Buffer buffer = _bufferFactory.GetNextFreeBuffer(); // prepare data - skip the 14-byte ethernet header buffer.AllocatedSize = (int)packetHeader.caplen - layer2Length; if (buffer.AllocatedSize > buffer.Data.Length) { Trace.WriteLine("RawPCap: packet length too large: " + buffer.AllocatedSize.ToString()); } else { Marshal.Copy(packetDataPtr + layer2Length, buffer.Data, 0, buffer.AllocatedSize); _bufferFactory.AddAllocatedBuffer(buffer); } } } catch (ThreadAbortException) { // do nothing, thread is aborting. return; } catch (Exception ex) { if (!bExceptionLogged) { Trace.WriteLine("WinPCap: Exception during RunCaptureLoop. " + ex.ToString()); } bExceptionLogged = true; // add sleep Thread.Sleep(100); } } }