/// <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); } } } } }