コード例 #1
0
        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");
            }
        }
コード例 #2
0
 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);
             }
         }
     }
 }
コード例 #3
0
ファイル: IPv6Packet.cs プロジェクト: esrever10/NetworkMiner
        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);
                }
            }
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        /// <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);
        }
コード例 #6
0
ファイル: IPv4Packet.cs プロジェクト: hatnetsec/NetworkMiner
        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);
                }
            }
        }
コード例 #7
0
ファイル: IPv6Packet.cs プロジェクト: mammo0/networkminer-cli
        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);
                }
            }
        }
コード例 #8
0
 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;
 }
コード例 #9
0
        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);
            }
        }