Skip to content

Commit 02f85fe

Browse files
SQLNA Fixed the firewall parser
1 parent 7bd06d2 commit 02f85fe

File tree

7 files changed

+59
-30
lines changed

7 files changed

+59
-30
lines changed
-3 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: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,16 @@ private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD* rawData)
9797
bool f_Wifi = ((rawData->EventHeader.Keyword) & 0x100) != 0; // process Wi-Fi events - not yet implemented
9898
Guid gu = (&rawData->EventHeader)->ProviderId;
9999
ushort eventID = rawData->EventHeader.Id;
100+
ushort WFPFragmentEventType = 0; // WFP fragments need to remove the fragment header in event type 2000
101+
uint WFPFragmentGroup = 0; // all fragments of the same packet have the same group number
102+
uint WFPFragmentLength = 0; // this is 10 less than the user payload length as header is 10 bytes in length
103+
bool WFPIncoming = ((rawData->EventHeader.Keyword) & 0x100000000) != 0; // only take incoming packets and reject outgoing ones 0x200000000
100104
Frame f = null;
101105
PartialFrame pf = null;
102106
byte[] userData = null;
103107

108+
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
109+
104110
// Debug.WriteLine($"TraceEvent_EventCallback: Frame:{m_eventCount + 1}, ProviderID: {gu}, NDIS: {NDIS}, PKTMON: {PKTMON}");
105111

106112
if (gu != NDIS && gu != PKTMON && gu != WFP)
@@ -130,14 +136,16 @@ private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD* rawData)
130136

131137
if (gu == WFP)
132138
{
133-
if (eventID != 60011 && eventID != 60012 && eventID != 60021 && eventID != 60022)
139+
if (eventID != 60011 && eventID != 60012 && eventID != 60021 && eventID != 60022 && eventID != 2000) // 2000 is a fragmented packet, needs special handling
140+
{
141+
m_eventCount++; // Track the count
142+
return;
143+
}
144+
if (!WFPIncoming) // easier to disable than if combined with the conditions above
134145
{
135146
m_eventCount++; // Track the count
136147
return;
137148
}
138-
// Only preocess PKTMON events that contain a network payload
139-
f_start = true; // Are these set for WFP captures?
140-
f_end = true;
141149
// Debug.WriteLine($"TraceEvent_EventCallback: It's a WFP event.");
142150
}
143151

@@ -156,13 +164,22 @@ private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD* rawData)
156164
// Program.logDiagnostic("Lost end of partial frame " + pf.f.frameNumber + " (PID=" + pf.ProcessID + ", TID=" + pf.ThreadID + ").");
157165
// Console.WriteLine("Lost end of partial frame " + pf.f.frameNumber + " (PID=" + pf.ProcessID + ", TID=" + pf.ThreadID + ").");
158166
}
159-
short arrayOffset = gu == PKTMON || gu == WFP ? (short)0 : NDIS_HEADER_LENGTH; // we want the pktmon/wfp header to be part of the data, not so with the NDIS header
160167
f = new Frame();
161168
f.frameNumber = m_eventCount;
162169
f.ticks = m_sessionStartTime.Ticks + ((long)(((rawData->EventHeader).TimeStamp - FirstTimeStamp) * 10000000 / m_QPCFreq));
163170
userData = new byte[rawData->UserDataLength - arrayOffset];
164171
var x = ((byte*)rawData->UserData);
165-
for (int i = 0; i < userData.Length; i++) userData[i] = x[i + arrayOffset];
172+
for (int i = 0; i < userData.Length; i++) userData[i] = x[i + arrayOffset]; // move bytes over
173+
174+
if (gu == WFP && eventID == 2000) // fragmented WFP packet
175+
{
176+
WFPFragmentEventType = utility.ReadUInt16(userData, 0);
177+
WFPFragmentGroup = utility.ReadUInt32(userData, 2);
178+
WFPFragmentLength = utility.ReadUInt32(userData, 6);
179+
byte[] temp = new byte[userData.Length - 10];
180+
Array.Copy(userData, 10, temp, 0, temp.Length); // copies from userData[10..userData.Length-1] to temp [0..temp.Length-11]
181+
userData = temp;
182+
}
166183
f.length = userData.Length;
167184
f.frameLength = (uint)userData.Length;
168185
f.bytesAvailable = (uint)userData.Length;
@@ -178,10 +195,10 @@ private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD* rawData)
178195
if (gu == WFP)
179196
{
180197
f.isWFP = true;
181-
f.EventType = eventID;
198+
f.EventType = eventID == 2000 ? WFPFragmentEventType : eventID; // use eventID for non-fragmented events and WFPFragmentEventType for fragmented ones
182199
}
183200

184-
if (f_end) // add Frame to FrameBuffer directly
201+
if (f_end) // add Frame to FrameBuffer directly - no fragmentation
185202
{
186203
lock (FrameBuffer)
187204
{
@@ -211,9 +228,20 @@ private void TraceEvent_EventCallback(TraceEventInterop.EVENT_RECORD* rawData)
211228
return;
212229
}
213230

214-
userData = new byte[rawData->UserDataLength - NDIS_HEADER_LENGTH];
231+
userData = new byte[rawData->UserDataLength - arrayOffset];
215232
var x = ((byte*)rawData->UserData);
216-
for (int i = 0; i < userData.Length; i++) userData[i] = x[i + NDIS_HEADER_LENGTH];
233+
for (int i = 0; i < userData.Length; i++) userData[i] = x[i + arrayOffset];
234+
235+
if (gu == WFP && eventID == 2000) // fragmented WFP packet
236+
{
237+
WFPFragmentEventType = utility.ReadUInt16(userData, 0);
238+
WFPFragmentGroup = utility.ReadUInt32(userData, 2);
239+
WFPFragmentLength = utility.ReadUInt32(userData, 6);
240+
byte[] temp = new byte[userData.Length - 10];
241+
Array.Copy(userData, 10, temp, 0, temp.Length); // copies from userData[10..userData.Length-1] to temp [0..temp.Length-11]
242+
userData = temp;
243+
}
244+
217245
pf.f.length += userData.Length;
218246
pf.f.frameLength += (uint)userData.Length;
219247
pf.f.bytesAvailable += (uint)userData.Length;

SQL_Network_Analyzer/SQLNA/Parser.cs

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,9 @@ public static void ParseWFPFrame(byte[] b, int offset, NetworkTrace t, FrameData
667667
ushort DPort = utility.B2UInt16(b, offset + 2);
668668
ConversationData c = t.GetIPV4Conversation(sourceIP, SPort, destIP, DPort); // adds conversation if new
669669

670+
// Is the Frame from Client or Server? This may be reversed later in ReverseBackwardConversations.
671+
if (sourceIP == c.sourceIP && SPort == c.sourcePort) f.isFromClient = true;
672+
670673
//
671674
// What: Determine whether the TCP client port has rolled around and is re-used and this should be a new conversation
672675
//
@@ -711,9 +714,6 @@ public static void ParseWFPFrame(byte[] b, int offset, NetworkTrace t, FrameData
711714
}
712715
f.conversation = c;
713716
c.AddFrame(f, t); // optionally add to the NetworkTrace frames collection, too
714-
715-
// Is the Frame from Client or Server? This may be reversed later in ReverseBackwardConversations.
716-
if (sourceIP == c.sourceIP) f.isFromClient = true;
717717
}
718718

719719
ParseNextProtocol(NextProtocol, b, offset, t, f);
@@ -723,13 +723,13 @@ public static void ParseWFPFrame(byte[] b, int offset, NetworkTrace t, FrameData
723723
case 60021: // WFP MessageV6
724724
case 60022: // WFP Message2V6
725725
{
726-
ulong sourceIPHi = utility.B2UInt64(b, offset); offset += 4;
727-
ulong sourceIPLo = utility.B2UInt64(b, offset); offset += 4;
728-
ulong destIPHi = utility.B2UInt64(b, offset); offset += 4;
729-
ulong destIPLo = utility.B2UInt64(b, offset); offset += 4;
726+
ulong sourceIPHi = utility.B2UInt64(b, offset); offset += 8;
727+
ulong sourceIPLo = utility.B2UInt64(b, offset); offset += 8;
728+
ulong destIPHi = utility.B2UInt64(b, offset); offset += 8;
729+
ulong destIPLo = utility.B2UInt64(b, offset); offset += 8;
730730
byte NextProtocol = b[offset]; offset++; // TCP = 6 UDP = 0x11 (17)
731731
if (eventID == 60022) offset += 8; // bypass FlowContext field in the Message2V4 record
732-
short payloadLength = (short)utility.B2UInt16(b, offset); offset += 2;
732+
short payloadLength = (short)utility.ReadUInt16(b, offset); offset += 2;
733733

734734
// determine the last element of b[] that contains IP64 data - also the last byte of TCP payload - ethernet may extend beyond this
735735
if (payloadLength == 0)
@@ -747,6 +747,9 @@ public static void ParseWFPFrame(byte[] b, int offset, NetworkTrace t, FrameData
747747
ushort DPort = utility.B2UInt16(b, offset + 2);
748748
ConversationData c = t.GetIPV6Conversation(sourceIPHi, sourceIPLo, SPort, destIPHi, destIPLo, DPort); // adds conversation if new
749749

750+
// Is the Frame from Client or Server? This may be reversed later in ReverseBackwardConversations.
751+
if (sourceIPHi == c.sourceIPHi && sourceIPLo == c.sourceIPLo && SPort == c.sourcePort) f.isFromClient = true;
752+
750753
//
751754
// What: Determine whether the TCP client port has rolled around and is re-used and this should be a new conversation
752755
//
@@ -791,9 +794,6 @@ public static void ParseWFPFrame(byte[] b, int offset, NetworkTrace t, FrameData
791794
}
792795
f.conversation = c;
793796
c.AddFrame(f, t); // optionally add to the NetworkTrace frames collection, too
794-
795-
// Is the Frame from Client or Server? This may be reversed later in ReverseBackwardConversations.
796-
if (sourceIPHi == c.sourceIPHi && sourceIPLo == c.sourceIPLo) f.isFromClient = true;
797797
}
798798

799799
ParseNextProtocol(NextProtocol, b, offset, t, f);
@@ -1200,6 +1200,9 @@ public static void ParseIPV4Frame(byte[] b, int offset, NetworkTrace t, FrameDat
12001200
DPort = utility.B2UInt16(b, offset + HeaderLength + 2);
12011201
ConversationData c = t.GetIPV4Conversation(sourceIP, SPort, destIP, DPort); // adds conversation if new
12021202

1203+
// Is the Frame from Client or Server? This may be reversed later in ReverseBackwardConversations.
1204+
if (sourceIP == c.sourceIP && SPort == c.sourcePort) f.isFromClient = true;
1205+
12031206
//
12041207
// Purpose: Do not record duplicate frames unless it has a PktmonData record associated with it
12051208
//
@@ -1219,7 +1222,7 @@ public static void ParseIPV4Frame(byte[] b, int offset, NetworkTrace t, FrameDat
12191222

12201223
int backCount = 0;
12211224

1222-
if (f.pktmon == null) // we want to see the pktmon trace points
1225+
if (f.pktmon == null) // we want to avoid the pktmon trace points
12231226
{
12241227
for (int j = c.frames.Count - 1; j >= 0; j--) // look in descending order for the same Packet ID number
12251228
{
@@ -1282,8 +1285,6 @@ public static void ParseIPV4Frame(byte[] b, int offset, NetworkTrace t, FrameDat
12821285
f.conversation = c;
12831286
c.AddFrame(f, t); // optionally add to the NetworkTrace frames collection, too
12841287

1285-
// Is the Frame from Client or Server? This may be reversed later in ReverseBackwardConversations.
1286-
if (sourceIP == c.sourceIP) f.isFromClient = true;
12871288
}
12881289

12891290
ParseNextProtocol(NextProtocol, b, offset + HeaderLength, t, f);
@@ -1346,6 +1347,10 @@ public static void ParseIPV6Frame(byte[] b, int offset, NetworkTrace t, FrameDat
13461347
SPort = utility.B2UInt16(b, offset + HeaderLength);
13471348
DPort = utility.B2UInt16(b, offset + HeaderLength + 2);
13481349
ConversationData c = t.GetIPV6Conversation(sourceIPHi, sourceIPLo, SPort, destIPHi, destIPLo, DPort);
1350+
1351+
//Is the Frame from Client or Server?
1352+
if (sourceIPHi == c.sourceIPHi && sourceIPLo == c.sourceIPLo && SPort == c.sourcePort) f.isFromClient = true;
1353+
13491354
//
13501355
// Determine whether the TCP client port has rolled around and this should be a new conversation
13511356
//
@@ -1384,10 +1389,6 @@ public static void ParseIPV6Frame(byte[] b, int offset, NetworkTrace t, FrameDat
13841389
}
13851390
f.conversation = c;
13861391
c.AddFrame(f, t);
1387-
1388-
//Is the Frame from Client or Server?
1389-
if (sourceIPHi == c.sourceIPHi && sourceIPLo == c.sourceIPLo)
1390-
f.isFromClient = true;
13911392
}
13921393

13931394
ParseNextProtocol(NextProtocol, b, offset + HeaderLength, t, f);

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.1963.0")]
36-
[assembly: AssemblyFileVersion("1.5.1963.0")]
35+
[assembly: AssemblyVersion("1.5.1974.0")]
36+
[assembly: AssemblyFileVersion("1.5.1974.0")]

0 commit comments

Comments
 (0)