Skip to content

Commit 3597fe8

Browse files
SQLNA Wifi and ETL TimeStamp improvements
1. Improved the WiFi parser to handle WiFi traffic in an ETL file, which is missing the Metadata header that's in a NETMON capture. 2. Fixed a silent data precision overflow error in the Event Header TimeStamp caused by a long trace and calculated using integer scaling. In ETLFileReader.
1 parent 57aa73c commit 3597fe8

File tree

10 files changed

+60
-17
lines changed

10 files changed

+60
-17
lines changed
-2 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

SQL_Network_Analyzer/SQLNA/ETLFileReader.cs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD* rawData)
9494
bool f_start = ((rawData->EventHeader.Keyword) & 0x40000000) != 0;
9595
bool f_end = ((rawData->EventHeader.Keyword) & 0x80000000) != 0;
9696
bool f_Ethernet8023 = ((rawData->EventHeader.Keyword) & 0x1) != 0; // process Ethernet events
97-
bool f_Wifi = ((rawData->EventHeader.Keyword) & 0x100) != 0; // process Wi-Fi events - not yet implemented
97+
bool f_Wifi = ((rawData->EventHeader.Keyword) & 0x10000) != 0; // process Wi-Fi events - Native802.11, not Wireless WAN
9898
Guid gu = (&rawData->EventHeader)->ProviderId;
9999
ushort eventID = rawData->EventHeader.Id;
100100
ushort WFPFragmentEventType = 0; // WFP fragments need to remove the fragment header in event type 2000
@@ -105,6 +105,14 @@ private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD* rawData)
105105
PartialFrame pf = null;
106106
byte[] userData = null;
107107

108+
// debug code
109+
//if (ProcessID == xxxx && ThreadID == xxxx)
110+
//{
111+
// Console.WriteLine(ThreadID.ToString()); // break on this line
112+
// // look at m_eventCount for the prior frame number
113+
//}
114+
// end debug code
115+
108116
short arrayOffset = gu == PKTMON || gu == WFP ? (short)0 : NDIS_HEADER_LENGTH; // we want the pktmon header to be part of the data, not so with the NDIS/wfp header
109117

110118
// Debug.WriteLine($"TraceEvent_EventCallback: Frame:{m_eventCount + 1}, ProviderID: {gu}, NDIS: {NDIS}, PKTMON: {PKTMON}");
@@ -166,7 +174,22 @@ private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD* rawData)
166174
}
167175
f = new Frame();
168176
f.frameNumber = m_eventCount;
169-
f.ticks = m_sessionStartTime.Ticks + ((long)(((rawData->EventHeader).TimeStamp - FirstTimeStamp) * 10000000 / m_QPCFreq));
177+
178+
// debug code
179+
//if (m_eventCount == 368198)
180+
//{
181+
// Console.WriteLine();
182+
//}
183+
// end debug code
184+
185+
if (m_QPCFreq == 10000000)
186+
{
187+
f.ticks = m_sessionStartTime.Ticks + ((long)(((rawData->EventHeader).TimeStamp - FirstTimeStamp))); // reduce math errors if the stopwatch frequency is 1 tick
188+
}
189+
else
190+
{
191+
f.ticks = m_sessionStartTime.Ticks + ((long)(((rawData->EventHeader).TimeStamp - FirstTimeStamp) * (double)(100000000 / m_QPCFreq)));
192+
}
170193
userData = new byte[rawData->UserDataLength - arrayOffset];
171194
var x = ((byte*)rawData->UserData);
172195
for (int i = 0; i < userData.Length; i++) userData[i] = x[i + arrayOffset]; // move bytes over
@@ -186,6 +209,10 @@ private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD* rawData)
186209
f.data = userData;
187210
f.linkType = (ushort)(f_Ethernet8023 ? 1 : f_Wifi ? 6 : 0); // Ethernet -> 1, Wifi -> 6, else 0
188211

212+
if (gu == NDIS)
213+
{
214+
f.isNDIS = true;
215+
}
189216
if (gu == PKTMON)
190217
{
191218
f.isPKTMON = true;

SQL_Network_Analyzer/SQLNA/OutputText.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,12 @@ private static void DisplayResetConnections(NetworkTrace Trace)
614614
rd.startOffset = ((FrameData)c.frames[0]).ticks - firstTick;
615615
rd.endTicks = ((FrameData)c.frames[c.frames.Count - 1]).ticks;
616616
rd.endOffset = rd.endTicks - firstTick;
617+
// debug code
618+
//if (rd.startOffset < 0 || rd.endOffset < 0)
619+
//{
620+
// Console.WriteLine($"First Tick: {firstTick}, Conv Start Tick: {((FrameData)c.frames[0]).ticks}, Conv End Tick: {rd.endTicks}");
621+
//}
622+
// end debug code
617623
rd.duration = rd.endOffset - rd.startOffset;
618624
rd.isClientReset = false;
619625
rd.rawRetransmits = c.rawRetransmits;

SQL_Network_Analyzer/SQLNA/Parser.cs

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ public static void ParseOneFile(string filePath, NetworkTrace t)
274274
}
275275
case 6: // WiFi
276276
{
277-
ParseWifiFrame(frame.data, 0, t, f); // TODO flesh this out
277+
ParseWifiFrame(frame.data, 0, t, f, frame.isNDIS); // TODO flesh this out
278278
// Test file: \Documents\Interesting Network Traces\WifiTrace\
279279
break;
280280
}
@@ -388,6 +388,8 @@ public static void ParseNextProtocol(uint ProtocolNumber, byte[] b, int offset,
388388
case 0x0800: // IPV4
389389
ParseIPV4Frame(b, offset, t, f);
390390
break;
391+
case 0x0806: // ARP - ignore and do not log
392+
break;
391393
case 0x8100: // 802.1Q
392394
Parse8021QFrame(b, offset, t, f);
393395
break;
@@ -398,6 +400,8 @@ public static void ParseNextProtocol(uint ProtocolNumber, byte[] b, int offset,
398400
case 0x22EB: // ERSPAN Type III
399401
ParseERSPANFrame(b, offset, t, f);
400402
break;
403+
case 0x88CC: // LLDP - 802.1 Link Layer Discovery Protocol - ignore and do not log
404+
break;
401405
case 0x8926: // VNETTag
402406
ParseVNTagFrame(b, offset, t, f);
403407
break;
@@ -499,6 +503,7 @@ public static void ParseNetEventFrame(byte[] b, int offset, NetworkTrace t, Fram
499503
Boolean isWifi = false;
500504
Boolean isFragment = false;
501505
Boolean isPktmon = false;
506+
Boolean isNDIS = false;
502507
ushort userDataLength = 0;
503508
uint ETLFragmentSize = 0;
504509

@@ -515,8 +520,9 @@ public static void ParseNetEventFrame(byte[] b, int offset, NetworkTrace t, Fram
515520
byte[] GuidBytes = new byte[16];
516521
Array.Copy(b, offset, GuidBytes, 0, 16);
517522
Guid ProviderID = new Guid(GuidBytes); // 0x6E00D62E29470946B4233EE7BCD678EF yields GUID {2ed6006e-4729-4609-b423-3ee7bcd678ef}
523+
isNDIS = ProviderID.Equals(NDIS);
518524
isPktmon = ProviderID.Equals(PKTMON);
519-
if (!ProviderID.Equals(NDIS) && !isPktmon) return; // not the provider we want
525+
if (!isNDIS && !isPktmon) return; // not the provider we want
520526
offset += 16;
521527

522528
// Read Descriptor - Event ID
@@ -568,7 +574,7 @@ public static void ParseNetEventFrame(byte[] b, int offset, NetworkTrace t, Fram
568574
}
569575
else if (isWifi)
570576
{
571-
ParseWifiFrame(b, offset, t, f);
577+
ParseWifiFrame(b, offset, t, f, isNDIS);
572578
}
573579
}
574580

@@ -937,7 +943,7 @@ public static void ParseEthernetFrame(byte[] b, int offset, NetworkTrace t, Fram
937943
}
938944
}
939945

940-
public static void ParseWifiFrame(byte[] b, int offset, NetworkTrace t, FrameData f)
946+
public static void ParseWifiFrame(byte[] b, int offset, NetworkTrace t, FrameData f, bool isNDIS)
941947
{
942948
byte version = 0;
943949
ushort metadataLength = 0;
@@ -951,16 +957,19 @@ public static void ParseWifiFrame(byte[] b, int offset, NetworkTrace t, FrameDat
951957
ulong destMAC = 0;
952958
ushort NextProtocol = 0; // IPV4 = 0x0800 (2048) IPV6 = 0x86DD (34525)
953959

954-
// Read Wifi Metadata
955-
version = b[offset];
956-
if (version != 2)
960+
if (isNDIS == false) // skip the metadata for NDIS captures; they start with the Frame Control
957961
{
958-
Program.logDiagnostic($"ParseWifiFrame. Frame {f.frameNo}. Unknown Wifi version: {version}");
959-
return;
960-
}
962+
// Read Wifi Metadata
963+
version = b[offset];
964+
if (version != 2)
965+
{
966+
Program.logDiagnostic($"ParseWifiFrame. Frame {f.frameNo}. Unknown Wifi version: {version}");
967+
return;
968+
}
961969

962-
metadataLength = utility.ReadUInt16(b, offset + 1);
963-
offset += metadataLength;
970+
metadataLength = utility.ReadUInt16(b, offset + 1);
971+
offset += metadataLength;
972+
}
964973

965974
// Read Frame Control
966975

SQL_Network_Analyzer/SQLNA/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ class Program
3232
// filterFormat A = AUTO, will perform NETMON or WirreShark filters based on the capture type ... ETL -> Netmon format
3333

3434
public static string VERSION_NUMBER = Assembly.GetExecutingAssembly().GetName().Version.ToString();
35-
public const string UPDATE_DATE = "2022/04/01";
35+
public const string UPDATE_DATE = "2024/01/01";
3636
public const string GITHUB_PROJECT_URL = "https://github.com/microsoft/CSS_SQL_Networking_Tools";
3737

3838
static void Main(string[] args)

SQL_Network_Analyzer/SQLNA/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,5 @@
3232
// You can specify all the values or you can default the Build and Revision Numbers
3333
// by using the '*' as shown below:
3434
// [assembly: AssemblyVersion("1.0.*")]
35-
[assembly: AssemblyVersion("1.5.2055.0")]
36-
[assembly: AssemblyFileVersion("1.5.2055.0")]
35+
[assembly: AssemblyVersion("1.5.2083.0")]
36+
[assembly: AssemblyFileVersion("1.5.2083.0")]

SQL_Network_Analyzer/SQLNA/ReaderBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class Frame
2121
public long ticks; // Absolute ticks of frame (calculated)
2222
public byte[] data; // Byte data for frame.
2323
public long length = 0; // Length of data in bytes.
24+
public bool isNDIS = false; // ETLFileReader sets this - if false, use the linkType to determine the parser
2425
public bool isPKTMON = false; // ETLFileReader sets this - if false, use the linkType to determine the parser
2526
public bool isWFP = false; // ETLFileReader sets this - if false, use the linkType to determine the parser
2627
public ushort EventType = 0; // ETLFileReader sets this

0 commit comments

Comments
 (0)