/// <summary>
        /// http://blogs.technet.com/b/netmon/archive/2009/10/07/using-nmapi-to-access-tcp-payload.aspx
        /// use property: property.tcppayloadlength, fields: tcp.srcport, tcp.dataoffset.dataoffset to calculate the payload length, and the offset in the raw frame.
        /// use NmGetPartialRawFrame to get the payload.
        /// </summary>
        private void GetTcpPayLoad()
        {
            unsafe
            {
                uint ret;
                byte tcpHeaderSize;            //
                uint tcpSrcOffset, tcpSrcSize; // offset: bits
                var  tcpPayloadLength = PropertyValueDict[NetmonPropertyName.TcpPayloadLength];
                int  payloadlen;
                bool result = Int32.TryParse(tcpPayloadLength.ToString(), out payloadlen);

                // Allocate a buffer for payload data. The maximum length=1460 bytes
                IntPtr buff = Marshal.AllocHGlobal(1500);
                if (payloadlen > 0)
                {
                    // Get the Data Offset, used to determine the TCP header size
                    ret = NetmonAPI.NmGetFieldValueNumber8Bit(_FrameInfoUnit.ParsedFrame, _FrameInfoUnit.FieldIdDict[NetmonFieldName.TcpDataSet], out tcpHeaderSize);
                    //Get the Offset of TCP.SrcPort which is the first field in TCP.
                    ret = NetmonAPI.NmGetFieldOffsetAndSize(_FrameInfoUnit.ParsedFrame, _FrameInfoUnit.FieldIdDict[NetmonFieldName.TcpSrcPort], out tcpSrcOffset, out tcpSrcSize);
                    // Read in the partial frame.  The Offset is in bits.  TCPHeaderSize is off by a factor of 4.
                    uint retlen;
                    uint offset = (uint)(tcpSrcOffset / 8 + tcpHeaderSize * 4);
                    ret = NetmonAPI.NmGetPartialRawFrame(_FrameInfoUnit.RawFrame, offset, (uint)payloadlen, (byte *)buff, out retlen);
                    // cast the intptr to the byte.
                    byte[] _payload = new byte[payloadlen];
                    Marshal.Copy(buff, _payload, 0, payloadlen);

                    //var str = Encoding.Default.GetString(_payload);
                    frameUnit.fieldUnit.PayLoad = _payload;

                    /*
                     * if (protocolname == "TCP")
                     * {
                     * frameUnit.fieldUnit.tcpPayLoad = _payload;
                     * }
                     * else
                     * {
                     * frameUnit.fieldUnit.httpPayLoad = _payload;
                     * // Console.WriteLine("http payload:");
                     * //Console.WriteLine(str);
                     * }*/
                }
                Marshal.Release(buff);
            }
        }
        public static string GetFramePayload(IntPtr RawFrame, uint TCPSrcOffset, uint TCPHeaderSize, uint paylen)
        {
            #region comm
            //string tempstring = string.Empty;
            //uint errno = 0;
            //byte[] result = null;

            //NM_NPL_PROPERTY_INFO propinfo = new NM_NPL_PROPERTY_INFO();
            //propinfo.Size = (ushort)System.Runtime.InteropServices.Marshal.SizeOf(propinfo);
            //errno = NetmonAPI.NmGetPropertyInfo(mFrameParser, mTCPPayLoadLengthID, ref propinfo);
            //if (errno != 0)
            //{
            //    Console.WriteLine("Error NmGetPropertyInfo Frame # error : " + errno.ToString());

            //}

            //byte[] val = new byte[propinfo.ValueSize];
            //uint retlen;
            //NmPropertyValueType vtype;
            //unsafe
            //{
            //    fixed (byte* pstr = val)
            //    {
            //        errno = NetmonAPI.NmGetPropertyById(mFrameParser, mTCPPayLoadLengthID, propinfo.ValueSize, pstr, out retlen, out vtype, 0, null);
            //    }
            //}

            //if (errno != 0)
            //{
            //    Console.WriteLine("Error NmGetPropertyById Frame" + errno.ToString());

            //}

            //uint paylen = (uint)val[0] + ((uint)val[1] << 8) + ((uint)val[2] << 16) + ((uint)val[3] << 24);

            //// Get the Data Offset, used to determine the TCP header size
            //byte TCPHeaderSize;
            //errno = NetmonAPI.NmGetFieldValueNumber8Bit(hParsedFrame, mTCPDataOffsetID, out TCPHeaderSize);
            //if (errno != 0)
            //{
            //    Console.WriteLine("Error NmGetFieldValueNumber8Bit Frame #error : " + errno.ToString());
            //}

            //// Get the Offset of TCP.SrcPort which is the first field in TCP.
            //uint TCPSrcOffset;
            //uint TCPSrcSize;
            //errno = NetmonAPI.NmGetFieldOffsetAndSize(hParsedFrame, mTCPSrcPortID, out TCPSrcOffset, out TCPSrcSize);
            //if (errno != 0)
            //{
            //    Console.WriteLine("Error NmGetFieldValueNumber8Bit Frame # error : " + errno.ToString());
            //}
            #endregion

            uint   retlen;
            uint   errno      = 0;
            byte[] result     = null;
            string tempstring = string.Empty;
            if (paylen > 0)
            {
                result = new byte[paylen];
                unsafe
                {
                    fixed(byte *pstr = result)
                    {
                        errno = NetmonAPI.NmGetPartialRawFrame(RawFrame, (uint)(TCPSrcOffset / 8 + TCPHeaderSize * 4), paylen, pstr, out retlen);
                        // errno = NetmonAPI.NmGetPartialRawFrame(RawFrame, (uint)(TCPSrcOffset / 8 ), paylen, pstr, out retlen);
                    }
                }

                if (errno != 0)
                {
                    Console.WriteLine("Error NmGetFieldValueNumber8Bit Frame #error : " + errno.ToString());
                    result = null;
                }
                else
                {
                    tempstring = Encoding.UTF8.GetString(result, 0, result.Length);
                }
            }
            else
            {
                retlen = 0;
            }

            return(tempstring);
        }
        /// <summary>
        /// Callback function for capture.
        /// </summary>
        /// <param name="hCapEngine"></param>
        /// <param name="adapterIndex"></param>
        /// <param name="callerContext"></param>
        /// <param name="hRawFrame"></param>
        private void CaptureCallBack(IntPtr hCapEngine, uint adapterIndex, IntPtr callerContext, IntPtr hRawFrame)
        {
            if (callerContext != IntPtr.Zero)
            {
                uint errno;

                unsafe
                {
                    uint frameLen = 0;

                    errno = NetmonAPI.NmGetRawFrameLength(hRawFrame, out frameLen);
                    if (errno != 0)
                    {
                        return;
                    }

                    byte[] frameBuf = new byte[CapturedFrameSize];

                    fixed(byte *pBuf = frameBuf)
                    {
                        if (frameLen >= CapturedFrameSize)
                        {
                            NM_TIME pTime = new NM_TIME();
                            //Get the TimeStamp of the frame for building the new shortened frame
                            errno = NetmonAPI.NmGetFrameTimeStampEx(hRawFrame, ref pTime);
                            if (errno != 0)
                            {
                                return;
                            }

                            uint captureSize = 0;
                            //use NmGetPartiaRawlFrame() to get the wanted length of the raw frame,
                            errno = NetmonAPI.NmGetPartialRawFrame(
                                hRawFrame,
                                0, //offset
                                CapturedFrameSize,
                                pBuf,
                                out captureSize
                                );
                            if (errno != 0)
                            {
                                return;
                            }

                            IntPtr hPartialRawFrame;
                            errno = NetmonAPI.NmBuildRawFrameFromBufferEx(
                                (IntPtr)pBuf,
                                CapturedFrameSize,
                                0, //media type, optional
                                ref pTime,
                                out hPartialRawFrame
                                );
                            if (errno != 0)
                            {
                                return;
                            }

                            NetmonAPI.NmAddFrame(callerContext, hPartialRawFrame);
                        }
                        else
                        {
                            NetmonAPI.NmAddFrame(callerContext, hRawFrame);
                        }
                    }
                }
            }
        }