Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions SQL_Network_Analyzer/SQLNA/ConversationData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ public class ConversationData // - constructed in GetI
public uint processID = 0;
public uint threadID = 0; // - set in GetClientPreloginInfo
public Guid connectionPeerID = Guid.Empty; // - set in GetClientPreloginInfo
public Guid peeractivityid = Guid.Empty;
public long peeractivityseq = 0; // ActivitySequence
public uint preloginFrameNumber = 0;

// Login Error and Delay Stats
public long synTime = 0; //
public long ackSynTime = 0; //
Expand Down
115 changes: 59 additions & 56 deletions SQL_Network_Analyzer/SQLNA/OutputText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3708,7 +3708,7 @@ private static void DisplayFooter()

private static void OutputStats(NetworkTrace Trace)
{
Program.logStat(@"SourceIP,SourcePort,DestIP,DestPort,IPVersion,Protocol,Syn,Fin,Reset,ZeroWindow,AckSynDelayms,Retransmit,ClientDup,ServerDup,KeepAlive,Integrated Login,NTLM,Login7,Encrypted,Mars,PacketVisualization,Pktmon,MaxPktmonDelay,PktmonDrop,PktmonDropReason,MaxPayloadSize,PayloadSizeLimit,Frames,Bytes,SentBytes,ReceivedBytes,Bytes/Sec,StartFile,EndFile,StartTime,EndTime,Duration,ClientTTL,ClientLowHops,ServerTTL,ServerLowHops,Connection_peer_id,ServerName,InstOpt,ServerVersion,DatabaseName,ServerTDSVersion,ClientTDSVersion,ServerTLSVersion,ClientTLSVersion,RedirSrv,RedirPort,Error,ErrorState,ErrorMessage,");
Program.logStat(@"SourceIP,SourcePort,DestIP,DestPort,IPVersion,Protocol,Syn,Fin,Reset,ZeroWindow,AckSynDelayms,Retransmit,ClientDup,ServerDup,KeepAlive,Integrated Login,NTLM,Login7,Encrypted,Mars,PacketVisualization,Pktmon,MaxPktmonDelay,PktmonDrop,PktmonDropReason,MaxPayloadSize,PayloadSizeLimit,Frames,Bytes,SentBytes,ReceivedBytes,Bytes/Sec,StartFile,EndFile,StartTime,EndTime,Duration,ClientTTL,ClientLowHops,ServerTTL,ServerLowHops, PreLoginFrameNumber,ConnectionID,ActivityId,ActivitySequence,ServerName,InstOpt,ServerVersion,DatabaseName,ServerTDSVersion,ClientTDSVersion,ServerTLSVersion,ClientTLSVersion,RedirSrv,RedirPort,Error,ErrorState,ErrorMessage,");

long traceFirstTick = 0;
if (Trace.frames != null && Trace.frames.Count > 0)
Expand All @@ -3734,61 +3734,64 @@ private static void OutputStats(NetworkTrace Trace)
}

Program.logStat(((c.isIPV6) ? utility.FormatIPV6Address(c.sourceIPHi, c.sourceIPLo) : utility.FormatIPV4Address(c.sourceIP)) + "," +
c.sourcePort + "," +
((c.isIPV6) ? utility.FormatIPV6Address(c.destIPHi, c.destIPLo) : utility.FormatIPV4Address(c.destIP)) + "," +
c.destPort + "," +
((c.isIPV6) ? "IPV6" : "IPV4") + "," +
GetProtocolName(c) + "," +
c.synCount + "," +
c.finCount + "," +
c.resetCount + "," +
(c.hasClientZeroWindow || c.hasServerZeroWindow ? "Y" : "") + "," +
(c.isUDP || c.ackSynTime == 0 ? "" : ((int)(c.LoginDelay("AS", firstTick) / utility.TICKS_PER_MILLISECOND)).ToString()) + "," +
c.rawRetransmits + "," +
c.duplicateClientPackets + "," +
c.duplicateServerPackets + "," +
c.keepAliveCount + "," +
(c.hasIntegratedSecurity ? "Y" : "") + "," +
(c.hasNTLMChallenge || c.hasNTLMResponse ? "Y" : "") + "," +
(c.hasLogin7 ? "Y" : "") + "," +
(c.isEncrypted ? (c.isEncRequired ? "R" : "Y") : "") + "," +
(c.isSQL && (c.isMARSEnabled || (c.smpAckCount + c.smpSynCount + c.smpFinCount + c.smpDataCount) > 0) ? "Y" : "") + "," +
(c.isUDP ? "" : c.frames.Count <= 40 ? c.GetPacketList(0, c.frames.Count) : c.GetFirstPacketList(20) + " ... " + c.GetLastPacketList(20)) + "," +
// Pktmon,MaxPktmonDelay,PktmonDrop,PktmonDropReason
(Trace.hasPktmonRecords ? "Y" : "") + "," +
(Trace.hasPktmonRecords ? $"{(c.pktmonMaxDelay / utility.TICKS_PER_SECOND).ToString("0.000000")}" : "") + "," +
(Trace.hasPktmonRecords && c.hasPktmonDroppedEvent ? $"Y" : "") + "," +
(Trace.hasPktmonRecords && c.hasPktmonDroppedEvent ? GetPktmonDropReasonText(c.pktmonDropReason) : "") + "," +
c.maxPayloadSize + "," +
(c.maxPayloadLimit ? "Y": "") + "," +
c.frames.Count + "," +
c.totalBytes + "," +
"," + // do not have a separate counter for sent bytes TODO ? do we really need it?
"," + // do not have a separate counter for received bytes TODO ? do we really need it?
(c.frames.Count > 1 ? (c.totalBytes * 1.0 / duration * utility.TICKS_PER_SECOND).ToString("0") : "") + "," +
firstFile + "," +
lastFile + "," +
new DateTime(firstTick).ToString(utility.TIME_FORMAT) + "," +
new DateTime(endTicks).ToString(utility.TIME_FORMAT) + "," +
(duration / utility.TICKS_PER_SECOND).ToString("0.000000") + "," +
(c.TTLCountOut == 0 ? "" : (c.TTLSumOut / c.TTLCountOut).ToString()) + "," +
(c.TTLCountOut == 0 ? "" : c.minTTLHopsOut.ToString()) + "," +
(c.TTLCountIn == 0 ? "" : (c.TTLSumIn / c.TTLCountIn).ToString()) + "," +
(c.TTLCountIn == 0 ? "" : c.minTTLHopsIn.ToString()) + "," +
(c.connectionPeerID == Guid.Empty ? "" : c.connectionPeerID.ToString().ToUpper()) + "," +
ServerName + "," +
(c.serverInstance == null ? "" : c.serverInstance) + "," +
ServerVersion + "," +
((c.databaseName == null) ? "" : c.databaseName) + "," +
c.FriendlyTDSVersionServer + "," +
c.FriendlyTDSVersionClient + "," +
((c.tlsVersionServer == null) ? "" : c.tlsVersionServer) + "," +
((c.tlsVersionClient == null) ? "" : c.tlsVersionClient) + "," +
c.RedirectServer.Replace(",", "<") + "," +
(c.RedirectPort == 0 ? "" : c.RedirectPort.ToString()) + "," +
(c.Error == 0 ? "" : c.Error.ToString()) + "," +
(c.ErrorState == 0 ? "" : c.ErrorState.ToString()) + "," +
c.ErrorMsg.Replace(",", ".")); // replace comma with period, otherwise this MUST be the last column
c.sourcePort + "," +
((c.isIPV6) ? utility.FormatIPV6Address(c.destIPHi, c.destIPLo) : utility.FormatIPV4Address(c.destIP)) + "," +
c.destPort + "," +
((c.isIPV6) ? "IPV6" : "IPV4") + "," +
GetProtocolName(c) + "," +
c.synCount + "," +
c.finCount + "," +
c.resetCount + "," +
(c.hasClientZeroWindow || c.hasServerZeroWindow ? "Y" : "") + "," +
(c.isUDP || c.ackSynTime == 0 ? "" : ((int)(c.LoginDelay("AS", firstTick) / utility.TICKS_PER_MILLISECOND)).ToString()) + "," +
c.rawRetransmits + "," +
c.duplicateClientPackets + "," +
c.duplicateServerPackets + "," +
c.keepAliveCount + "," +
(c.hasIntegratedSecurity ? "Y" : "") + "," +
(c.hasNTLMChallenge || c.hasNTLMResponse ? "Y" : "") + "," +
(c.hasLogin7 ? "Y" : "") + "," +
(c.isEncrypted ? (c.isEncRequired ? "R" : "Y") : "") + "," +
(c.isSQL && (c.isMARSEnabled || (c.smpAckCount + c.smpSynCount + c.smpFinCount + c.smpDataCount) > 0) ? "Y" : "") + "," +
(c.isUDP ? "" : c.frames.Count <= 40 ? c.GetPacketList(0, c.frames.Count) : c.GetFirstPacketList(20) + " ... " + c.GetLastPacketList(20)) + "," +
// Pktmon,MaxPktmonDelay,PktmonDrop,PktmonDropReason
(Trace.hasPktmonRecords ? "Y" : "") + "," +
(Trace.hasPktmonRecords ? $"{(c.pktmonMaxDelay / utility.TICKS_PER_SECOND).ToString("0.000000")}" : "") + "," +
(Trace.hasPktmonRecords && c.hasPktmonDroppedEvent ? $"Y" : "") + "," +
(Trace.hasPktmonRecords && c.hasPktmonDroppedEvent ? GetPktmonDropReasonText(c.pktmonDropReason) : "") + "," +
c.maxPayloadSize + "," +
(c.maxPayloadLimit ? "Y" : "") + "," +
c.frames.Count + "," +
c.totalBytes + "," +
"," + // do not have a separate counter for sent bytes TODO ? do we really need it?
"," + // do not have a separate counter for received bytes TODO ? do we really need it?
(c.frames.Count > 1 ? (c.totalBytes * 1.0 / duration * utility.TICKS_PER_SECOND).ToString("0") : "") + "," +
firstFile + "," +
lastFile + "," +
new DateTime(firstTick).ToString(utility.TIME_FORMAT) + "," +
new DateTime(endTicks).ToString(utility.TIME_FORMAT) + "," +
(duration / utility.TICKS_PER_SECOND).ToString("0.000000") + "," +
(c.TTLCountOut == 0 ? "" : (c.TTLSumOut / c.TTLCountOut).ToString()) + "," +
(c.TTLCountOut == 0 ? "" : c.minTTLHopsOut.ToString()) + "," +
(c.TTLCountIn == 0 ? "" : (c.TTLSumIn / c.TTLCountIn).ToString()) + "," +
(c.TTLCountIn == 0 ? "" : c.minTTLHopsIn.ToString()) + "," +
(c.preloginFrameNumber) + "," +
(c.connectionPeerID == Guid.Empty ? "" : c.connectionPeerID.ToString().ToUpper()) + "," +
(c.peeractivityid == Guid.Empty ? "" : c.peeractivityid.ToString().ToUpper()) + "," +
c.peeractivityseq + "," +
ServerName + "," +
(c.serverInstance == null ? "" : c.serverInstance) + "," +
ServerVersion + "," +
((c.databaseName == null) ? "" : c.databaseName) + "," +
c.FriendlyTDSVersionServer + "," +
c.FriendlyTDSVersionClient + "," +
((c.tlsVersionServer == null) ? "" : c.tlsVersionServer) + "," +
((c.tlsVersionClient == null) ? "" : c.tlsVersionClient) + "," +
c.RedirectServer.Replace(",", "<") + "," +
(c.RedirectPort == 0 ? "" : c.RedirectPort.ToString()) + "," +
(c.Error == 0 ? "" : c.Error.ToString()) + "," +
(c.ErrorState == 0 ? "" : c.ErrorState.ToString()) + "," +
c.ErrorMsg.Replace(",", ".")); // replace comma with period, otherwise this MUST be the last column
}
}

Expand Down
16 changes: 13 additions & 3 deletions SQL_Network_Analyzer/SQLNA/TDSParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class TDSParser
}

// helper function
private static void GetClientPreloginInfo(byte[] tdsPayLoad, ConversationData conv)
private static void GetClientPreloginInfo(byte[] tdsPayLoad, ConversationData conv, uint frameNumber = 0)
{
UInt16 majorVersion, minorVersion, levelVersion;
UInt16 offset, length;
Expand All @@ -78,6 +78,9 @@ private static void GetClientPreloginInfo(byte[] tdsPayLoad, ConversationData co
if (8 + offset >= tdsPayLoad.Length)
return;

//Prelogin packet frame#
conv.preloginFrameNumber = frameNumber;

switch (tdsPayLoad[i])
{
case 0: // Client TDS Version; - needs work - TODO
Expand All @@ -100,12 +103,19 @@ private static void GetClientPreloginInfo(byte[] tdsPayLoad, ConversationData co
case 4: // MARS options.
if (tdsPayLoad[8 + offset] == 1) conv.isMARSEnabled = true;
break;
case 5: // ConnectionID (16 byte GUID) and ActivityID (20 bytes) - ignoring ActivityID as we don't need it
case 5: // ConnectionID (16 byte GUID) and ActivityID 16 bytes GUID + 4 bytes sequence number (UINT)
if (length == 36)
{
byte[] guidBytes = new byte[16];
Array.Copy(tdsPayLoad, 8 + offset, guidBytes, 0, 16);
conv.connectionPeerID = new Guid(guidBytes);

Array.Copy(tdsPayLoad, (8 + offset + 16), guidBytes, 0, 16);
conv.peeractivityid = new Guid(guidBytes);

//peer_activity_seq
conv.peeractivityseq = utility.ReadUInt32(tdsPayLoad, (8 + offset + 32));

}
break;
default:
Expand Down Expand Up @@ -386,7 +396,7 @@ public static void ProcessTDS(NetworkTrace trace)

if (preloginType == 0) // Prelogin packet
{
GetClientPreloginInfo(fd.payload, fd.conversation);
GetClientPreloginInfo(fd.payload, fd.conversation, fd.frameNo);
c.hasPrelogin = true;
fd.frameType = FrameType.PreLogin;
if (c.PreLoginTime == 0) c.PreLoginTime = fd.ticks;
Expand Down