private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD *rawData) // write buffering layer to reassemble pakets & remove extraneous material. { if (FirstTimeStamp == 0) { FirstTimeStamp = (rawData->EventHeader).TimeStamp; } int ProcessID = rawData->EventHeader.ProcessId; int ThreadID = rawData->EventHeader.ThreadId; bool f_start = ((rawData->EventHeader.Keyword) & 0x40000000) != 0; bool f_end = ((rawData->EventHeader.Keyword) & 0x80000000) != 0; bool f_Ethernet8023 = ((rawData->EventHeader.Keyword) & 0x1) != 0; // process Ethernet events bool f_Wifi = ((rawData->EventHeader.Keyword) & 0x100) != 0; // process Wi-Fi events - not yet implemented Guid gu = (&rawData->EventHeader)->ProviderId; ushort eventID = rawData->EventHeader.Id; Frame f = null; PartialFrame pf = null; byte[] userData = null; // Debug.WriteLine($"TraceEvent_EventCallback: Frame:{m_eventCount + 1}, ProviderID: {gu}, NDIS: {NDIS}, PKTMON: {PKTMON}"); if (gu != NDIS && gu != PKTMON) { m_eventCount++; // assuming no fragmentation of events return; // process only NDIS and PKTMON events } if (gu == NDIS && f_Ethernet8023 == false && f_Wifi == false) // added Ethernet/Wi-Fi check to ignore non-parsable events { m_eventCount++; // assuming no fragmentation of non-NDIS events. could be wrong, but no way of knowing. return; // process only NDIS events } if (gu == PKTMON) { if (eventID != 160 && eventID != 170) { m_eventCount++; // Track the count return; } // Only preocess PKTMON events that contain a network payload f_start = true; // these flags aren't set for PKTMON captures, but are used by the logic below, so set both to TRUE to get the effect we want f_end = true; // Debug.WriteLine($"TraceEvent_EventCallback: It's a PKTMON event."); } if (f_start) // data complete in a single event or the initial fragment of several { m_eventCount++; // only increment on the initial event // remove partial event from the PartialFrameBuffer pf = GetPartialFrame(ProcessID, ThreadID); if (pf != null) { PartialFrameBuffer.Remove(pf); // Houston, we lost an event somewhere // *** TODO *** Log it properly // causes a race condition in memory for some traces... // Program.logDiagnostic("Lost end of partial frame " + pf.f.frameNumber + " (PID=" + pf.ProcessID + ", TID=" + pf.ThreadID + ")."); // Console.WriteLine("Lost end of partial frame " + pf.f.frameNumber + " (PID=" + pf.ProcessID + ", TID=" + pf.ThreadID + ")."); } short arrayOffset = gu == PKTMON ? (short)0 : NDIS_HEADER_LENGTH; // we want the pktmon header to be part of the data, not so with the NDIS header f = new Frame(); f.frameNumber = m_eventCount; f.ticks = m_sessionStartTime.Ticks + ((long)(((rawData->EventHeader).TimeStamp - FirstTimeStamp) * 10000000 / m_QPCFreq)); userData = new byte[rawData->UserDataLength - arrayOffset]; var x = ((byte *)rawData->UserData); for (int i = 0; i < userData.Length; i++) { userData[i] = x[i + arrayOffset]; } f.length = userData.Length; f.frameLength = (uint)userData.Length; f.bytesAvailable = (uint)userData.Length; f.data = userData; f.linkType = (ushort)(f_Ethernet8023 ? 1 : f_Wifi ? 6 : 0); // Ethernet -> 1, Wifi -> 6, else 0 if (gu == PKTMON) { f.isPKTMON = true; f.pktmonEventType = eventID; } if (f_end) // add Frame to FrameBuffer directly { lock (FrameBuffer) { FrameBuffer.Add(f); f = null; } } else // add partial frame to PartialFrameBuffer { pf = new PartialFrame(); pf.ProcessID = ProcessID; pf.ThreadID = ThreadID; pf.f = f; PartialFrameBuffer.Add(pf); } } else // intermediate or terminal fragment of several { pf = GetPartialFrame(ProcessID, ThreadID); if (pf == null) { // Houston, something happened; toss the event and log // *** TODO *** Log it properly // causes a race condition in memory // Program.logDiagnostic("Lost start of partial frame ~ " + (m_eventCount + 1) + " (PID=" + ProcessID + ", TID=" + ThreadID + ")."); // Console.WriteLine("Lost start of partial frame ~ " + (m_eventCount + 1) + " (PID=" + ProcessID + ", TID=" + ThreadID + ")."); return; } userData = new byte[rawData->UserDataLength - NDIS_HEADER_LENGTH]; var x = ((byte *)rawData->UserData); for (int i = 0; i < userData.Length; i++) { userData[i] = x[i + NDIS_HEADER_LENGTH]; } pf.f.length += userData.Length; pf.f.frameLength += (uint)userData.Length; pf.f.bytesAvailable += (uint)userData.Length; pf.f.data = ConcatBytes(pf.f.data, userData); if (f_end) { PartialFrameBuffer.Remove(pf); // done with this - let's fill the Frame Buffer lock (FrameBuffer) { FrameBuffer.Add(pf.f); } } } }
private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD *rawData) // write buffering layer to reassemble pakets & remove extraneous material. { if (FirstTimeStamp == 0) { FirstTimeStamp = (rawData->EventHeader).TimeStamp; } int ProcessID = rawData->EventHeader.ProcessId; int ThreadID = rawData->EventHeader.ThreadId; bool f_start = ((rawData->EventHeader.Keyword) & 0x40000000) != 0; bool f_end = ((rawData->EventHeader.Keyword) & 0x80000000) != 0; bool f_Ethernet8023 = ((rawData->EventHeader.Keyword) & 0x1) != 0; // process Ethernet events bool f_Wifi = ((rawData->EventHeader.Keyword) & 0x100) != 0; // process Wi-Fi events - not yet implemented Guid gu = (&rawData->EventHeader)->ProviderId; Frame f = null; PartialFrame pf = null; byte[] userData = null; if (gu != NDIS || (f_Ethernet8023 == false && f_Wifi == false)) // added Ethernet/Wi-Fi check to ignore non-parsable events { m_eventCount++; // assuming no fragmentation of non-NDIS events. could be wrong, but no way of knowing. return; // process only NDIS events } if (f_start) // data complete in a single event or the initial fragment of several { m_eventCount++; // only increment on the initial event // remove partial event from the PartialFrameBuffer pf = GetPartialFrame(ProcessID, ThreadID); if (pf != null) { PartialFrameBuffer.Remove(pf); // Houston, we lost an event somewhere // *** TODO *** Log it properly Program.logDiagnostic("Lost end of partial frame " + pf.f.frameNumber + " (PID=" + pf.ProcessID + ", TID=" + pf.ThreadID + ")."); // Console.WriteLine("Lost end of partial frame " + pf.f.frameNumber + " (PID=" + pf.ProcessID + ", TID=" + pf.ThreadID + ")."); } f = new Frame(); f.frameNumber = m_eventCount; f.ticks = m_sessionStartTime.Ticks + ((long)(((rawData->EventHeader).TimeStamp - FirstTimeStamp) * 10000000 / m_QPCFreq)); userData = new byte[rawData->UserDataLength - NDIS_HEADER_LENGTH]; var x = ((byte *)rawData->UserData); for (int i = 0; i < userData.Length; i++) { userData[i] = x[i + NDIS_HEADER_LENGTH]; } f.length = userData.Length; f.frameLength = (uint)userData.Length; f.bytesAvailable = (uint)userData.Length; f.data = userData; f.linkType = (ushort)(f_Ethernet8023 ? 1 : f_Wifi ? 6 : 0); // Ethernet -> 1, Wifi -> 6, else 0 if (f_end) // add Frame to FrameBuffer directly { lock (FrameBuffer) { FrameBuffer.Add(f); f = null; } } else // add partial frame to PartialFrameBuffer { pf = new PartialFrame(); pf.ProcessID = ProcessID; pf.ThreadID = ThreadID; pf.f = f; PartialFrameBuffer.Add(pf); } } else // intermediate or terminal fragment of several { pf = GetPartialFrame(ProcessID, ThreadID); if (pf == null) { // Houston, something happened; toss the event and log // *** TODO *** Log it properly Program.logDiagnostic("Lost start of partial frame ~ " + (m_eventCount + 1) + " (PID=" + ProcessID + ", TID=" + ThreadID + ")."); // Console.WriteLine("Lost start of partial frame ~ " + (m_eventCount + 1) + " (PID=" + ProcessID + ", TID=" + ThreadID + ")."); return; } userData = new byte[rawData->UserDataLength - NDIS_HEADER_LENGTH]; var x = ((byte *)rawData->UserData); for (int i = 0; i < userData.Length; i++) { userData[i] = x[i + NDIS_HEADER_LENGTH]; } pf.f.length += userData.Length; pf.f.frameLength += (uint)userData.Length; pf.f.bytesAvailable += (uint)userData.Length; pf.f.data = ConcatBytes(pf.f.data, userData); if (f_end) { PartialFrameBuffer.Remove(pf); // done with this - let's fill the Frame Buffer lock (FrameBuffer) { FrameBuffer.Add(pf.f); } } } }