public NetworkTcpSession(Packets.TcpPacket tcpSynPacket, NetworkHost clientHost, NetworkHost serverHost, ISessionProtocolFinderFactory protocolFinderFactory) { if (tcpSynPacket.FlagBits.Synchronize) //It's normal to start the session with a SYN flag { FiveTuple fiveTuple = new FiveTuple(clientHost, tcpSynPacket.SourcePort, serverHost, tcpSynPacket.DestinationPort, FiveTuple.TransportProtocol.TCP); this.flow = new NetworkFlow(fiveTuple, tcpSynPacket.ParentFrame.Timestamp, tcpSynPacket.ParentFrame.Timestamp, 0, 0); //this.synPacketTimestamp=tcpSynPacket.ParentFrame.Timestamp; //this.clientHost=clientHost; //this.serverHost=serverHost; //this.clientTcpPort=tcpSynPacket.SourcePort; //this.serverTcpPort=tcpSynPacket.DestinationPort; this.synPacketReceived = false; this.synAckPacketReceived = false; this.finPacketReceived = false; this.clientToServerFinPacketSequenceNumber = UInt32.MaxValue; this.serverToClientFinPacketSequenceNumber = UInt32.MaxValue; this.sessionEstablished = false; this.sessionClosed = false; this.startFrameNumber = tcpSynPacket.ParentFrame.FrameNumber; this.clientToServerTcpDataStream = null; this.serverToClientTcpDataStream = null; this.protocolFinder = protocolFinderFactory.CreateProtocolFinder(this.flow, this.startFrameNumber); } else { throw new Exception("SYN flag not set on TCP packet"); } }
internal void SetTcpData(Packets.TcpPacket tcpPacket) { this.sourceTcpPort = tcpPacket.SourcePort; this.destinationTcpPort = tcpPacket.DestinationPort; this.tcpPacketByteCount = tcpPacket.PacketByteCount; //this.sourceHost.AddSentPacketFromTcpPort(tcpPacket.SourcePort);//this info is in the NetworkPacketList instead if (tcpPacket.FlagBits.Synchronize) { this.tcpSynFlag = true; if (tcpPacket.FlagBits.Acknowledgement) { this.tcpSynAckFlag = true; if (!sourceHost.TcpPortIsOpen(tcpPacket.SourcePort)) { this.sourceHost.AddOpenTcpPort(tcpPacket.SourcePort); } } } }
public override IEnumerable <AbstractPacket> GetSubPackets(bool includeSelfReference) { if (includeSelfReference) { yield return(this); } if (PacketStartIndex + 40 < PacketEndIndex) { AbstractPacket packet; try { if (this.nextHeader == (byte)IPv4Packet.RFC1700Protocols.TCP) { //TCP packet packet = new TcpPacket(this.ParentFrame, PacketStartIndex + 40, PacketEndIndex);//bugg? } else if (this.nextHeader == (byte)IPv4Packet.RFC1700Protocols.UDP) { //UDP packet packet = new UdpPacket(this.ParentFrame, PacketStartIndex + 40, PacketEndIndex); } else if (this.nextHeader == (byte)IPv4Packet.RFC1700Protocols.GRE) { //GRE packet packet = new GrePacket(this.ParentFrame, PacketStartIndex + 40, PacketEndIndex); } else { packet = new RawPacket(ParentFrame, PacketStartIndex + 40, PacketEndIndex); } } catch (Exception) { packet = new RawPacket(ParentFrame, PacketStartIndex + 40, PacketEndIndex); } yield return(packet); foreach (AbstractPacket subPacket in packet.GetSubPackets(false)) { yield return(subPacket); } } }
public bool TryAddPacket(Packets.TcpPacket tcpPacket, NetworkHost sourceHost, NetworkHost destinationHost) { if (this.sessionClosed) { return(false); } //Make sure the hosts are correct if (sourceHost == this.ClientHost && tcpPacket.SourcePort == this.ClientTcpPort)//client -> server { if (destinationHost != this.ServerHost) { return(false); } if (tcpPacket.SourcePort != this.ClientTcpPort) { return(false); } if (tcpPacket.DestinationPort != this.ServerTcpPort) { return(false); } } else if (sourceHost == this.ServerHost && tcpPacket.SourcePort == this.ServerTcpPort)//server -> client { if (destinationHost != ClientHost) { return(false); } if (tcpPacket.SourcePort != ServerTcpPort) { return(false); } if (tcpPacket.DestinationPort != ClientTcpPort) { return(false); } } else//unknown direction { return(false); } //this.latestPacketTimestamp=tcpPacket.ParentFrame.Timestamp; this.flow.EndTime = tcpPacket.ParentFrame.Timestamp; //Check TCP handshake if (!this.synPacketReceived) //SYN (client->server) { if (tcpPacket.FlagBits.Synchronize && sourceHost == this.ClientHost) { this.synPacketReceived = true; } else { return(false); } } else if (!this.synAckPacketReceived) //SYN+ACK (server->client) { if (tcpPacket.FlagBits.Synchronize && tcpPacket.FlagBits.Acknowledgement && sourceHost == this.ServerHost) { this.synAckPacketReceived = true; } else { return(false); } } else if (!this.sessionEstablished) //ACK (client->server) { if (tcpPacket.FlagBits.Acknowledgement && sourceHost == this.ClientHost) { this.SetEstablished(tcpPacket.SequenceNumber, tcpPacket.AcknowledgmentNumber); } else { return(false); } } //FIN and RST is handeled lower down //else{//an established and not closed session! if (tcpPacket.PayloadDataLength > 0) { this.protocolFinder.AddPacket(tcpPacket, sourceHost, destinationHost); try { //If we've come this far the packet should be allright for the networkSession byte[] tcpSegmentData = tcpPacket.GetTcpPacketPayloadData(); //now add the data to the server to calculate service statistics for the open port NetworkServiceMetadata networkServiceMetadata = null; lock (this.ServerHost.NetworkServiceMetadataList) { if (!this.ServerHost.NetworkServiceMetadataList.ContainsKey(this.ServerTcpPort)) { networkServiceMetadata = new NetworkServiceMetadata(this.ServerHost, this.ServerTcpPort); this.ServerHost.NetworkServiceMetadataList.Add(this.ServerTcpPort, networkServiceMetadata); } else { networkServiceMetadata = this.ServerHost.NetworkServiceMetadataList[this.ServerTcpPort]; } } //now, lets extract some data from the TCP packet! if (sourceHost == this.ServerHost && tcpPacket.SourcePort == this.ServerTcpPort) { networkServiceMetadata.OutgoingTraffic.AddTcpPayloadData(tcpSegmentData); //this.clientToServerTcpDataStream.AddTcpData(tcpPacket.SequenceNumber, tcpSegmentData); if (this.serverToClientTcpDataStream == null) { this.serverToClientTcpDataStream = new TcpDataStream(tcpPacket.SequenceNumber, false, this); } if (this.requiredNextTcpDataStreamIsClientToServer == null && this.serverToClientTcpDataStream.TotalByteCount == 0) { this.requiredNextTcpDataStreamIsClientToServer = false; } this.serverToClientTcpDataStream.AddTcpData(tcpPacket.SequenceNumber, tcpSegmentData); } else { networkServiceMetadata.IncomingTraffic.AddTcpPayloadData(tcpSegmentData); //this.serverToClientTcpDataStream.AddTcpData(tcpPacket.SequenceNumber, tcpSegmentData); if (this.clientToServerTcpDataStream == null) { this.clientToServerTcpDataStream = new TcpDataStream(tcpPacket.SequenceNumber, true, this); } if (this.requiredNextTcpDataStreamIsClientToServer == null && this.clientToServerTcpDataStream.TotalByteCount == 0) { this.requiredNextTcpDataStreamIsClientToServer = true; } this.clientToServerTcpDataStream.AddTcpData(tcpPacket.SequenceNumber, tcpSegmentData); } } catch (Exception ex) { if (!tcpPacket.ParentFrame.QuickParse) { tcpPacket.ParentFrame.Errors.Add(new Frame.Error(tcpPacket.ParentFrame, tcpPacket.PacketStartIndex, tcpPacket.PacketEndIndex, ex.Message)); } return(false); } } //} //se if stream should be closed if (tcpPacket.FlagBits.Reset)//close no matter what { this.Close(); } else if (tcpPacket.FlagBits.Fin)//close nicely { if (!this.finPacketReceived) { this.finPacketReceived = true; if (sourceHost == this.ServerHost && tcpPacket.SourcePort == this.ServerTcpPort) { this.serverToClientFinPacketSequenceNumber = tcpPacket.SequenceNumber; } else { this.clientToServerFinPacketSequenceNumber = tcpPacket.SequenceNumber; } } else if (tcpPacket.FlagBits.Acknowledgement)//fin+ack { this.Close(); } } return(true); }
/// <summary> /// Creates a truncated TCP session where the initial 3 way handshake is missing /// </summary> /// <param name="sourceHost"></param> /// <param name="destinationHost"></param> /// <param name="tcpPacket"></param> public NetworkTcpSession(NetworkHost sourceHost, NetworkHost destinationHost, Packets.TcpPacket tcpPacket, ISessionProtocolFinderFactory protocolFinderFactory) { //this part is used to create a cropped (truncated) session where the beginning is missing! //this.synPacketTimestamp=tcpPacket.ParentFrame.Timestamp; this.synPacketReceived = true; this.synAckPacketReceived = true; this.finPacketReceived = false; this.sessionEstablished = false;//I will change this one soon,... this.sessionClosed = false; this.startFrameNumber = tcpPacket.ParentFrame.FrameNumber; this.clientToServerTcpDataStream = null; this.serverToClientTcpDataStream = null; //now let's do a qualified guess of who is the server and who is client... FiveTuple fiveTuple; System.Collections.Generic.List <ApplicationLayerProtocol> sourcePortProtocols = new List <ApplicationLayerProtocol>(TcpPortProtocolFinder.GetProbableApplicationLayerProtocols(tcpPacket.SourcePort, tcpPacket.SourcePort)); System.Collections.Generic.List <ApplicationLayerProtocol> destinationPortProtocols = new List <ApplicationLayerProtocol>(TcpPortProtocolFinder.GetProbableApplicationLayerProtocols(tcpPacket.DestinationPort, tcpPacket.DestinationPort)); if (sourcePortProtocols.Count > destinationPortProtocols.Count) //packet is server -> client //this.clientHost=destinationHost; //this.serverHost=sourceHost; //this.clientTcpPort=tcpPacket.DestinationPort; //this.serverTcpPort=tcpPacket.SourcePort; { fiveTuple = new FiveTuple(destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, FiveTuple.TransportProtocol.TCP); this.flow = new NetworkFlow(fiveTuple, tcpPacket.ParentFrame.Timestamp, tcpPacket.ParentFrame.Timestamp, 0, 0); this.SetEstablished(tcpPacket.AcknowledgmentNumber, tcpPacket.SequenceNumber); } else if (destinationPortProtocols.Count > 0) //packet is client -> server //this.clientHost=sourceHost; //this.serverHost=destinationHost; //this.clientTcpPort=tcpPacket.SourcePort; //this.serverTcpPort=tcpPacket.DestinationPort; { fiveTuple = new FiveTuple(sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, FiveTuple.TransportProtocol.TCP); this.flow = new NetworkFlow(fiveTuple, tcpPacket.ParentFrame.Timestamp, tcpPacket.ParentFrame.Timestamp, 0, 0); this.SetEstablished(tcpPacket.SequenceNumber, tcpPacket.AcknowledgmentNumber); } else if (tcpPacket.SourcePort < tcpPacket.DestinationPort)//packet is server -> client //this.clientHost=destinationHost; //this.serverHost=sourceHost; //this.clientTcpPort=tcpPacket.DestinationPort; //this.serverTcpPort=tcpPacket.SourcePort; { fiveTuple = new FiveTuple(destinationHost, tcpPacket.DestinationPort, sourceHost, tcpPacket.SourcePort, FiveTuple.TransportProtocol.TCP); this.flow = new NetworkFlow(fiveTuple, tcpPacket.ParentFrame.Timestamp, tcpPacket.ParentFrame.Timestamp, 0, 0); this.SetEstablished(tcpPacket.AcknowledgmentNumber, tcpPacket.SequenceNumber); } else //packet is client -> server //this.clientHost=sourceHost; //this.serverHost=destinationHost; //this.clientTcpPort=tcpPacket.SourcePort; //this.serverTcpPort=tcpPacket.DestinationPort; { fiveTuple = new FiveTuple(sourceHost, tcpPacket.SourcePort, destinationHost, tcpPacket.DestinationPort, FiveTuple.TransportProtocol.TCP); this.flow = new NetworkFlow(fiveTuple, tcpPacket.ParentFrame.Timestamp, tcpPacket.ParentFrame.Timestamp, 0, 0); this.SetEstablished(tcpPacket.SequenceNumber, tcpPacket.AcknowledgmentNumber); } this.protocolFinder = protocolFinderFactory.CreateProtocolFinder(this.flow, this.startFrameNumber); }
public override IEnumerable <AbstractPacket> GetSubPackets(bool includeSelfReference) { if (includeSelfReference) { yield return(this); } if (this.fragmentOffset != 0 || this.moreFragmentsFlag) { if (!this.ParentFrame.QuickParse) { byte[] reassembledIpFrameData = null; string fragmentID = this.GetFragmentIdentifier(); lock (PacketHandler.Ipv4Fragments) { List <IPv4Packet> ipPacketList; if (!PacketHandler.Ipv4Fragments.ContainsKey(fragmentID)) { ipPacketList = new List <IPv4Packet>(); PacketHandler.Ipv4Fragments.Add(fragmentID, ipPacketList); } else { ipPacketList = PacketHandler.Ipv4Fragments[fragmentID]; } ipPacketList.Add(this); //see if we have all fragments of a complete IP packet bool allFragmentsHaveMoreFragmentsFlag = true; int completeIpPacketPayloadLength = 0; foreach (IPv4Packet p in ipPacketList) { completeIpPacketPayloadLength += p.PayloadLength; if (!p.moreFragmentsFlag) { allFragmentsHaveMoreFragmentsFlag = false; } } if (!allFragmentsHaveMoreFragmentsFlag) { //we might actually have all the fragments! reassembledIpFrameData = new byte[this.HeaderLength + completeIpPacketPayloadLength]; if (reassembledIpFrameData.Length > UInt16.MaxValue) { PacketHandler.Ipv4Fragments.Remove(fragmentID); yield break; } foreach (IPv4Packet p in ipPacketList) { if (p.fragmentOffset + this.HeaderLength + p.PayloadLength > reassembledIpFrameData.Length) { yield break; } Array.Copy(p.ParentFrame.Data, p.PacketStartIndex + p.HeaderLength, reassembledIpFrameData, p.fragmentOffset + this.HeaderLength, p.PayloadLength); } PacketHandler.Ipv4Fragments.Remove(fragmentID);//we don't want to reassemble this IP frame any more //we now need to create a fake frame and run GetSubPackets(false) on it } }//Release lock on PacketHandler.Ipv4Fragments if (reassembledIpFrameData != null && reassembledIpFrameData.Length > this.HeaderLength) { Array.Copy(this.ParentFrame.Data, this.PacketStartIndex, reassembledIpFrameData, 0, this.headerLength); //totalLength = (ushort)reassembledIpFrameData.Length; Utils.ByteConverter.ToByteArray((ushort)reassembledIpFrameData.Length, reassembledIpFrameData, 2); //moreFragmentsFlag = false; //fragmentOffset = 0; reassembledIpFrameData[6] = 0; reassembledIpFrameData[7] = 0; Frame reassembledFrame = new Frame(this.ParentFrame.Timestamp, reassembledIpFrameData, ParentFrame.FrameNumber); IPv4Packet reassembledIpPacket = new IPv4Packet(reassembledFrame, 0, reassembledFrame.Data.Length - 1); reassembledIpPacket.fragmentOffset = 0; reassembledIpPacket.moreFragmentsFlag = false; reassembledIpPacket.totalLength = (ushort)reassembledIpFrameData.Length; foreach (AbstractPacket subPacket in reassembledIpPacket.GetSubPackets(false)) { yield return(subPacket); } } } } else if (PacketStartIndex + headerLength < PacketEndIndex && this.fragmentOffset == 0) { AbstractPacket packet; try { if (this.protocol == (byte)IPv4Packet.RFC1700Protocols.TCP) { //TCP packet if (PacketStartIndex + headerLength + 20 > PacketEndIndex + 1) { yield break;//too little room for a TCP packet } else { packet = new TcpPacket(this.ParentFrame, PacketStartIndex + headerLength, PacketEndIndex); } } else if (this.protocol == (byte)IPv4Packet.RFC1700Protocols.UDP) { //UDP packet if (PacketStartIndex + headerLength + 8 > PacketEndIndex + 1) { yield break;//too little room for a UDP packet } else { packet = new UdpPacket(this.ParentFrame, PacketStartIndex + headerLength, PacketEndIndex); } } else if (this.protocol == (byte)IPv4Packet.RFC1700Protocols.SCTP) { //SCTP packet packet = new SctpPacket(this.ParentFrame, PacketStartIndex + headerLength, PacketEndIndex); } else if (this.protocol == (byte)IPv4Packet.RFC1700Protocols.IPv6) { packet = new IPv6Packet(this.ParentFrame, PacketStartIndex + headerLength, PacketEndIndex); } else if (this.protocol == (byte)IPv4Packet.RFC1700Protocols.GRE) { packet = new GrePacket(this.ParentFrame, PacketStartIndex + headerLength, PacketEndIndex); } else if (this.protocol == (byte)IPv4Packet.RFC1700Protocols.ICMP) { packet = new IcmpPacket(this.ParentFrame, PacketStartIndex + headerLength, PacketEndIndex); } else { packet = new RawPacket(ParentFrame, PacketStartIndex + headerLength, PacketEndIndex); } } catch (Exception) { packet = new RawPacket(ParentFrame, PacketStartIndex + headerLength, PacketEndIndex); } yield return(packet); foreach (AbstractPacket subPacket in packet.GetSubPackets(false)) { yield return(subPacket); } } }
public override IEnumerable <AbstractPacket> GetSubPackets(bool includeSelfReference) { if (includeSelfReference) { yield return(this); } if (PacketStartIndex + 40 < PacketEndIndex) { AbstractPacket packet; try { if (this.nextHeader == (byte)IPv4Packet.RFC1700Protocols.TCP) { //TCP packet if (PacketStartIndex + 40 + 20 > PacketEndIndex + 1) { yield break;//too little room for a TCP packet } else { packet = new TcpPacket(this.ParentFrame, PacketStartIndex + 40, PacketEndIndex);//bugg? } } else if (this.nextHeader == (byte)IPv4Packet.RFC1700Protocols.UDP) { //UDP packet if (PacketStartIndex + 40 + 8 > PacketEndIndex + 1) { yield break;//too little room for a UDP packet } else { packet = new UdpPacket(this.ParentFrame, PacketStartIndex + 40, PacketEndIndex); } } else if (this.nextHeader == (byte)IPv4Packet.RFC1700Protocols.SCTP) { //SCTP packet packet = new SctpPacket(this.ParentFrame, PacketStartIndex + 40, PacketEndIndex); } else if (this.nextHeader == (byte)IPv4Packet.RFC1700Protocols.GRE) { //GRE packet packet = new GrePacket(this.ParentFrame, PacketStartIndex + 40, PacketEndIndex); } else { packet = new RawPacket(ParentFrame, PacketStartIndex + 40, PacketEndIndex); } } catch (Exception e) { SharedUtils.Logger.Log("Error parsing packet in IPv6 payload in " + this.ParentFrame.ToString() + ". " + e.ToString(), SharedUtils.Logger.EventLogEntryType.Warning); packet = new RawPacket(ParentFrame, PacketStartIndex + 40, PacketEndIndex); } yield return(packet); foreach (AbstractPacket subPacket in packet.GetSubPackets(false)) { yield return(subPacket); } } }
private TpktPacket(Frame parentFrame, int packetStartIndex, int packetEndIndex, TcpPacket parentTcpPacket) : base(parentFrame, packetStartIndex, packetEndIndex, "TPKT") { this.version = parentFrame.Data[packetStartIndex]; this.length = Utils.ByteConverter.ToUInt16(parentFrame.Data, packetStartIndex + 2, false); this.parentTcpPacket = parentTcpPacket; }
public static bool TryParse(Frame parentFrame, int packetStartIndex, int packetEndIndex, TcpPacket parentTcpPacket, out AbstractPacket result) { result = null; if (parentFrame.Data[packetStartIndex] != 3)//"This field is always 3 for the version of the protocol described in this memo." { return(false); } if (parentFrame.Data[packetStartIndex + 1] != 0)//the "reserved" value should be 0 { return(false); } ushort length = Utils.ByteConverter.ToUInt16(parentFrame.Data, packetStartIndex + 2, false); if (length > packetEndIndex - packetStartIndex + 1 || length < 4) { return(false); } try { result = new TpktPacket(parentFrame, packetStartIndex, packetEndIndex, parentTcpPacket); } catch { result = null; } if (result == null) { return(false); } else { return(true); } }