private void Receive(IpPacket ipPacket) { var protocol = ipPacket.Protocol; if (protocol != IPProtocolType.TCP) { return; } if (ipPacket.PayloadPacket == null) { return; } var tcpPacket = new TcpPacket(new ByteArraySegment(ipPacket.PayloadPacket.BytesHighPerformance)); var isFirstPacket = tcpPacket.Syn; var sourceIp = new IPAddress(ipPacket.SourceAddress.GetAddressBytes()).ToString(); var destinationIp = new IPAddress(ipPacket.DestinationAddress.GetAddressBytes()).ToString(); var connectionId = new ConnectionId(sourceIp, tcpPacket.SourcePort, destinationIp, tcpPacket.DestinationPort); lock (_lock) { TcpConnection connection; bool isInterestingConnection; if (isFirstPacket) { connection = new TcpConnection(connectionId, tcpPacket.SequenceNumber); OnNewConnection(connection); isInterestingConnection = connection.HasSubscribers; if (!isInterestingConnection) { return; } _connections[connectionId] = connection; Debug.Assert(ipPacket.PayloadPacket.PayloadData.Length == 0); } else { isInterestingConnection = _connections.TryGetValue(connectionId, out connection); if (!isInterestingConnection) { return; } if (!string.IsNullOrEmpty(TcpLogFile)) { File.AppendAllText(TcpLogFile, string.Format("{0} {1}+{4} | {2} {3}+{4} ACK {5} ({6})\r\n", connection.CurrentSequenceNumber, tcpPacket.SequenceNumber, connection.BytesReceived, connection.SequenceNumberToBytesReceived(tcpPacket.SequenceNumber), ipPacket.PayloadLength, tcpPacket.AcknowledgmentNumber, connection.BufferedPacketDescription)); } connection.HandleTcpReceived(tcpPacket.SequenceNumber, new ByteArraySegment(ipPacket.PayloadPacket.PayloadData)); } } }
private void Receive(ArraySegment<byte> ipData) { var ipPacket = new Ip4Packet(ipData); var protocol = ipPacket.Protocol; if (protocol != IpProtocol.Tcp) return; var tcpPacket = new TcpPacket(ipPacket.Payload); bool isFirstPacket = (tcpPacket.Flags & TcpFlags.Syn) != 0; var connectionId = new ConnectionId(ipPacket.SourceIp, tcpPacket.SourcePort, ipPacket.DestinationIp, tcpPacket.DestinationPort); lock (_lock) { TcpConnection connection; bool isInterestingConnection; if (isFirstPacket) { connection = new TcpConnection(connectionId, tcpPacket.SequenceNumber); OnNewConnection(connection); isInterestingConnection = connection.HasSubscribers; if (!isInterestingConnection) return; _connections[connectionId] = connection; Debug.Assert(tcpPacket.Payload.Count == 0); } else { isInterestingConnection = _connections.TryGetValue(connectionId, out connection); if (!isInterestingConnection) return; if (!string.IsNullOrEmpty(TcpLogFile)) File.AppendAllText(TcpLogFile, string.Format("{0} {1}+{4} | {2} {3}+{4} ACK {5} ({6})\r\n", connection.CurrentSequenceNumber, tcpPacket.SequenceNumber, connection.BytesReceived, connection.SequenceNumberToBytesReceived(tcpPacket.SequenceNumber), tcpPacket.Payload.Count, tcpPacket.AcknowledgementNumber, connection.BufferedPacketDescription)); connection.HandleTcpReceived(tcpPacket.SequenceNumber, tcpPacket.Payload); } } }
protected void OnEndConnection(TcpConnection connection) { var handler = EndConnection; handler?.Invoke(connection); }
protected void OnNewConnection(TcpConnection connection) { var handler = NewConnection; if (handler != null) handler(connection); }
// called from the tcp sniffer, so it needs to lock void HandleTcpDataReceived(TcpConnection connection, ArraySegment<byte> data) { lock (_eventLock) { if (data.Count == 0) return; if (_isNew.Contains(connection)) { _isNew.Remove(connection); if (_serversByIp.ContainsKey(connection.Source.Address.ToString()) && data.Array.Skip(data.Offset).Take(4).SequenceEqual(new byte[] { 1, 0, 0, 0 })) { var server = _serversByIp[connection.Source.Address.ToString()]; _serverToClient = connection; _clientToServer = null; _decrypter = new ConnectionDecrypter(); _decrypter.ClientToServerDecrypted += HandleClientToServerDecrypted; _decrypter.ServerToClientDecrypted += HandleServerToClientDecrypted; _messageSplitter = new MessageSplitter(); _messageSplitter.MessageReceived += HandleMessageReceived; OnNewConnection(server); } if (_serverToClient != null && _clientToServer == null && (_serverToClient.Destination.Equals(connection.Source) && _serverToClient.Source.Equals(connection.Destination))) { _clientToServer = connection; } } if (!(connection == _clientToServer || connection == _serverToClient)) return; if (_decrypter == null) return; var dataArray = data.Array.Skip(data.Offset).Take(data.Count).ToArray(); if (connection == _clientToServer) _decrypter.ClientToServer(dataArray); else _decrypter.ServerToClient(dataArray); } }
// called from the tcp sniffer, so it needs to lock void HandleNewConnection(TcpConnection connection) { lock (_eventLock) { if (!_serversByIp.ContainsKey(connection.Destination.Address.ToString()) && !_serversByIp.ContainsKey(connection.Source.Address.ToString())) return; _isNew.Add(connection); connection.DataReceived += HandleTcpDataReceived; } }
//private void ParsePacketsLoop() //{ // while (true) // { // QPacket toProcess; // if (_buffer.TryDequeue(out toProcess)) // toProcess.Connection.HandleTcpReceived(toProcess.SequenceNumber, toProcess.Packet); // else System.Threading.Thread.Sleep(1); // } //} private void Receive(IPv4Packet ipData) { var tcpPacket = ipData.PayloadPacket as PacketDotNet.TcpPacket; if (tcpPacket == null || tcpPacket.DataOffset*4 > ipData.PayloadLength) return; //if (tcpPacket.Checksum!=0 && !tcpPacket.ValidTCPChecksum) return; var isFirstPacket = tcpPacket.Syn; var connectionId = new ConnectionId(ipData.SourceAddress, tcpPacket.SourcePort, ipData.DestinationAddress, tcpPacket.DestinationPort); TcpConnection connection; bool isInterestingConnection; if (isFirstPacket) { connection = new TcpConnection(connectionId, tcpPacket.SequenceNumber, RemoveConnection, SnifferType); OnNewConnection(connection); isInterestingConnection = connection.HasSubscribers; if (!isInterestingConnection) return; _connections[connectionId] = connection; Debug.Assert(tcpPacket.PayloadData.Length == 0); } else { isInterestingConnection = _connections.TryGetValue(connectionId, out connection); if (!isInterestingConnection) return; byte[] payload; try { payload = tcpPacket.PayloadData; } catch { return; } //_buffer.Enqueue(new QPacket(connection, tcpPacket.SequenceNumber, tcpPacket.Payload)); lock (_lock) connection.HandleTcpReceived(tcpPacket.SequenceNumber, payload); //if (!string.IsNullOrEmpty(TcpLogFile)) // File.AppendAllText(TcpLogFile, // string.Format("{0} {1}+{4} | {2} {3}+{4} ACK {5} ({6})\r\n", // connection.CurrentSequenceNumber, tcpPacket.SequenceNumber, connection.BytesReceived, // connection.SequenceNumberToBytesReceived(tcpPacket.SequenceNumber), // tcpPacket.Payload.Count, tcpPacket.AcknowledgementNumber, // connection.BufferedPacketDescription)); } }
protected void OnNewConnection(TcpConnection connection) { var handler = NewConnection; handler?.Invoke(connection); }
internal void RemoveConnection(TcpConnection connection) { TcpConnection temp; if (_connections.ContainsKey(connection.ConnectionId)) _connections.TryRemove(connection.ConnectionId, out temp); }
//private void ParsePacketsLoop() //{ // while (true) // { // QPacket toProcess; // if (_buffer.TryDequeue(out toProcess)) // toProcess.Connection.HandleTcpReceived(toProcess.SequenceNumber, toProcess.Packet); // else System.Threading.Thread.Sleep(1); // } //} private void Receive(IPv4Packet ipData) { var tcpPacket = ipData.PayloadPacket as TcpPacket; if (tcpPacket == null || tcpPacket.DataOffset * 4 > ipData.PayloadLength) { return; } //if (tcpPacket.Checksum!=0 && !tcpPacket.ValidTCPChecksum) return; var isFirstPacket = tcpPacket.Synchronize; var connectionId = new ConnectionId(ipData.SourceAddress, tcpPacket.SourcePort, ipData.DestinationAddress, tcpPacket.DestinationPort); TcpConnection connection; bool isInterestingConnection; if (isFirstPacket) { connection = new TcpConnection(connectionId, tcpPacket.SequenceNumber, RemoveConnection, SnifferType); OnNewConnection(connection); isInterestingConnection = connection.HasSubscribers; if (!isInterestingConnection) { return; } _connections[connectionId] = connection; Debug.Assert(tcpPacket.PayloadData.Length == 0); } else { isInterestingConnection = _connections.TryGetValue(connectionId, out connection); if (!isInterestingConnection) { return; } byte[] payload; try { payload = tcpPacket.PayloadData; } catch { return; } //_buffer.Enqueue(new QPacket(connection, tcpPacket.SequenceNumber, tcpPacket.Payload)); lock (_lock) { if (tcpPacket.Finished || tcpPacket.Reset) { OnEndConnection(connection); return; } if (payload == null) { return; } connection.HandleTcpReceived(tcpPacket.SequenceNumber, payload); } //if (!string.IsNullOrEmpty(TcpLogFile)) // File.AppendAllText(TcpLogFile, // string.Format("{0} {1}+{4} | {2} {3}+{4} ACK {5} ({6})\r\n", // connection.CurrentSequenceNumber, tcpPacket.SequenceNumber, connection.BytesReceived, // connection.SequenceNumberToBytesReceived(tcpPacket.SequenceNumber), // tcpPacket.Payload.Count, tcpPacket.AcknowledgementNumber, // connection.BufferedPacketDescription)); } }
// called from the tcp sniffer, so it needs to lock private void HandleTcpDataReceived(TcpConnection connection, byte[] data, int needToSkip) { { if (data.Length == 0) { if (needToSkip==0 || !(connection == _clientToServer || connection == _serverToClient)) return; if (_decrypter == null) return; if (connection == _clientToServer) _decrypter.Skip(MessageDirection.ClientToServer, needToSkip); else _decrypter.Skip(MessageDirection.ServerToClient, needToSkip); return; } if (_isNew.ContainsKey(connection)) { if (_serversByIp.ContainsKey(connection.Source.Address.ToString()) && data.Take(4).SequenceEqual(new byte[] {1, 0, 0, 0})) { byte q; _isNew.TryRemove(connection, out q); var server = _serversByIp[connection.Source.Address.ToString()]; _serverToClient = connection; _clientToServer = null; ServerProxyOverhead = (int) connection.BytesReceived; _decrypter = new ConnectionDecrypter(server.Region); _decrypter.ClientToServerDecrypted += HandleClientToServerDecrypted; _decrypter.ServerToClientDecrypted += HandleServerToClientDecrypted; _messageSplitter = new MessageSplitter(); _messageSplitter.MessageReceived += HandleMessageReceived; _messageSplitter.Resync += OnResync; OnNewConnection(server); } if (_serverToClient != null && _clientToServer == null && _serverToClient.Destination.Equals(connection.Source) && _serverToClient.Source.Equals(connection.Destination)) { ClientProxyOverhead=(int)connection.BytesReceived; byte q; _isNew.TryRemove(connection, out q); _clientToServer = connection; } if (connection.BytesReceived > 0x10000) //if received more bytes but still not recognized - not interesting. { byte q; _isNew.TryRemove(connection, out q); connection.DataReceived -= HandleTcpDataReceived; connection.RemoveCallback(); } } if (!(connection == _clientToServer || connection == _serverToClient)) return; if (_decrypter == null) return; if (connection == _clientToServer) _decrypter.ClientToServer(data, needToSkip); else _decrypter.ServerToClient(data, needToSkip); } }
// called from the tcp sniffer, so it needs to lock private void HandleNewConnection(TcpConnection connection) { { if (!_serversByIp.ContainsKey(connection.Destination.Address.ToString()) && !_serversByIp.ContainsKey(connection.Source.Address.ToString())) return; _isNew.TryAdd(connection,1); connection.DataReceived += HandleTcpDataReceived; } }
private void Receive(ArraySegment <byte> ipData) { var ipPacket = new Ip4Packet(ipData); var protocol = ipPacket.Protocol; if (protocol != IpProtocol.Tcp) { return; } var tcpPacket = new TcpPacket(ipPacket.Payload); if (tcpPacket.Bad) { return; } var isFirstPacket = (tcpPacket.Flags & TcpFlags.Syn) != 0; var connectionId = new ConnectionId(ipPacket.SourceIp, tcpPacket.SourcePort, ipPacket.DestinationIp, tcpPacket.DestinationPort); lock (_lock) { TcpConnection connection; bool isInterestingConnection; if (isFirstPacket) { connection = new TcpConnection(connectionId, tcpPacket.SequenceNumber); OnNewConnection(connection); isInterestingConnection = connection.HasSubscribers; if (!isInterestingConnection) { return; } _connections[connectionId] = connection; Debug.Assert(tcpPacket.Payload.Count == 0); } else { isInterestingConnection = _connections.TryGetValue(connectionId, out connection); if (!isInterestingConnection) { return; } if ((ipPacket.Flags & 1) == 1) { BasicTeraData.LogError("Fragmented packet"); } if (!string.IsNullOrEmpty(TcpLogFile)) { File.AppendAllText(TcpLogFile, string.Format("{0} {1}+{4} | {2} {3}+{4} ACK {5} ({6})\r\n", connection.CurrentSequenceNumber, tcpPacket.SequenceNumber, connection.BytesReceived, connection.SequenceNumberToBytesReceived(tcpPacket.SequenceNumber), tcpPacket.Payload.Count, tcpPacket.AcknowledgementNumber, connection.BufferedPacketDescription)); } connection.HandleTcpReceived(tcpPacket.SequenceNumber, tcpPacket.Payload); } } }