예제 #1
0
파일: RawSocket.cs 프로젝트: zhyupe/machina
 public int Receive(out byte[] buffer)
 {
     // retrieve data from allocated buffer.
     NetworkBufferFactory.Buffer data = _socketState.bufferFactory.GetNextAllocatedBuffer();
     buffer = data?.Data;
     return(data?.AllocatedSize ?? 0);
 }
예제 #2
0
파일: RawSocket.cs 프로젝트: zhyupe/machina
 public void FreeBuffer(ref byte[] buffer)
 {
     NetworkBufferFactory.Buffer data = new NetworkBufferFactory.Buffer()
     {
         Data = buffer, AllocatedSize = 0
     };
     _socketState.bufferFactory.AddFreeBuffer(data);
 }
예제 #3
0
파일: RawSocket.cs 프로젝트: zhyupe/machina
        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");
            }
        }
예제 #4
0
        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);
                }
            }
        }