Beispiel #1
0
        public unsafe int Receive(out byte[] buffer)
        {
            buffer = _buffer;

            if (_activeDevice == null)
            {
                return(0);
            }

            try
            {
                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)
                {
                    // todo: log?
                    return(0);
                }
                else if (status != 0)
                {
                    pcap_pkthdr packetHeader = *(pcap_pkthdr *)packetHeaderPtr;

                    if (packetHeader.caplen <= layer2Length)
                    {
                        return(0);
                    }

                    // prepare data - skip the 14-byte ethernet header
                    int size = (int)packetHeader.caplen - layer2Length;
                    if (size > _buffer.Length)
                    {
                        throw new ApplicationException("packet length too large: " + size.ToString());
                    }

                    Marshal.Copy(packetDataPtr + layer2Length, _buffer, 0, size);

                    return(size);
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Exception during WinPCap Receive. " + ex.ToString());
            }

            return(0);
        }
Beispiel #2
0
        // out param so that we can change assign p and s to new mem locations,
        // since ReadNext calls 'new' to p and s.
        /// <summary>
        /// Read the next available packet from the capture driver.
        /// Returns if timeout specified in Open elapsed, or a packet has been
        /// forwarded by the capture driver.
        /// </summary>
        /// <param name="p">Packet header of the packet returned</param>
        /// <param name="packet_data">Packet data of the packet returned</param>
        /// <returns></returns>
        private PCAP_NEXT_EX_STATE ReadNextInternal(out PacketHeader p, out byte[] packet_data, out IntPtr pkthdr, out IntPtr pktdata)
        {
            pkthdr      = IntPtr.Zero;
            pktdata     = IntPtr.Zero;
            p           = null;
            packet_data = null;
            if (this.pcap_t.ToInt32() == 0)
            {
                this.errbuf = new StringBuilder("No adapter is currently open");
                return(PCAP_NEXT_EX_STATE.ERROR);
            }

            int ret = pcap_next_ex(this.pcap_t, ref pkthdr, ref pktdata);

            //System.Diagnostics.Debug.WriteLine(this.pcap_t);
            if (ret == 0)
            {
                return(PCAP_NEXT_EX_STATE.TIMEOUT);
            }
            else if (ret == 1)
            {
                pcap_pkthdr packetheader = (pcap_pkthdr)Marshal.PtrToStructure(pkthdr,
                                                                               typeof(pcap_pkthdr));
                p           = new PacketHeader();
                p.Caplength = (int)packetheader.caplen;
                p.Length    = (int)packetheader.len;
                p.ts        = packetheader.ts;
                packet_data = new byte[p.Length];
                Marshal.Copy(pktdata, packet_data, 0, p.Caplength);
                return(PCAP_NEXT_EX_STATE.SUCCESS);
            }
            else if (ret == -1)
            {
                return(PCAP_NEXT_EX_STATE.ERROR);
            }
            else if (ret == -2)
            {
                return(PCAP_NEXT_EX_STATE.EOF);
            }
            else
            {
                return(PCAP_NEXT_EX_STATE.UNKNOWN);
            }
        }
Beispiel #3
0
        // Creates a new Bro packet from libpcap packet header information and packet data.
        internal BroPacket(timeval timestamp, uint captureLength, byte[] packetData, string tag = null)
        {
            if ((object)packetData == null)
            {
                throw new ArgumentNullException("packetData");
            }

            pcap_pkthdr header = new pcap_pkthdr();

            header.ts     = timestamp;
            header.caplen = captureLength;
            header.len    = (uint)packetData.Length;

            m_packetPtr = BroApi.bro_packet_new(ref header, packetData, tag);

            if (m_packetPtr.IsInvalid())
            {
                throw new OutOfMemoryException("Failed to create Bro packet.");
            }
        }
Beispiel #4
0
 public static extern char[] pcap_next(long pcap_handle, pcap_pkthdr header);
Beispiel #5
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);
                }
            }
        }