Ejemplo n.º 1
0
        public override string ToString()
        {
            StringBuilder s = new StringBuilder();

            for (int i = 0; i < 2; i++)
            {
                s.Append("List" + i.ToString() + "\r\n");
                foreach (DictionaryEntry item in List[i])
                {
                    TCPState state = item.Value as TCPState;
                    s.Append(item.Key.ToString() + ":" + state.State.ToString() + "\r\n");
                }
            }
            return(s.ToString());
        }
Ejemplo n.º 2
0
        public void EndOfStream(TCPState state, int direction, string result)
        {
            Association Assoc = (Association)state.UserInfo;
            if(Assoc != null)  // i.e. if DICOM
            {
                lock(Assoc)
                {
                    OutputHandler("End : " + state.Signature[0] + "\r\n" + result + "\r\n",true,true);
                    Assoc.Out(result + "\r\n",true);
                    Assoc.HandleEnd();

                    if((state.State[0] != TCPState.States.RUNNING) && (state.State[1] != TCPState.States.RUNNING))  // i.e. if DICOM
                    {

                        state.Clear(); // should have been done elsewhere, but no harm to repeat

                        // Select the first association from the list by default
                        snifferObj.Invoke(snifferObj.SelectConnectionHandler);
                    }

                    //Handle incomplete byte stream
                    if((result.IndexOf("DEAD data seen") != -1) &&
                        (((state.State[0] != TCPState.States.RUNNING) && (state.State[1] != TCPState.States.FINISHED)) ||
                        ((state.State[0] != TCPState.States.FINISHED) && (state.State[1] != TCPState.States.RUNNING))))
                    {
                        Assoc.Dispose(true);
                        state.Clear();
                    }

                    //Handle unexpected Abort
                    if(result == "Forced Close")
                    {
                        Assoc.Dispose(true);
                        state.Clear();
                    }
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// This is the main routine called from TCP layer for handling DICOM data
        /// </summary>
        /// <param name="state"></param>
        /// <param name="direction"></param>
        public void ReceiveTCPData(TCPState state, int direction)
        {
            byte[] p = state.data[direction];
            int length = (int)state.Position[direction];
            uint Position = 0;
            Association Assoc = (Association)state.UserInfo;
            bool TryAnotherPDU = true;

            while(length >= Position + 6 && TryAnotherPDU)
            {
                TryAnotherPDU = false;
                byte PDUType = p[Position];
                uint Index = Position + 2;
                uint PDULength = DICOMUtility.Get4BytesBigEndian( p , ref Index);

                if(Assoc == null && PDUType == 1)
                {
                    Assoc = new Association(state, BaseFileName + state.Signature[0], System.DateTime.Now);
                    Assoc.Output += new Association.OutputEvent(OutputHandler);
                    state.UserInfo = Assoc;
                    string signature = state.Signature[0];
                    list.Add(signature,Assoc);
                    OutputHandler("New : " + signature + "\r\n",true,true);
            //                    snifferObj.Invoke(snifferObj.AddConnectionHandler, new object[] { signature });
                }

                if(Assoc !=null && length >= Index + PDULength)
                {
                    lock(Assoc)
                    {
                        Assoc.HandlePDU(p,Position,PDULength,direction, state);
                        TryAnotherPDU = true;
                    }
                }
                else if(length>64000 && Assoc==null) // non-DICOM
                {
                    OutputHandler("Non-DICOM data : " + state.Signature[0] + "\r\n",true,true);
                    break;  // don't process any more if we have a currently unhandleable PDU
                }
                else
                {
                    break;  // don't prcess any more if we have a currently unhandleable PDU
                }
                Position += PDULength + 6;
            }

            if(Position > 0 )
            {
                if(state.data[direction] != null)
                {
                    state.UsedData(Position, direction);
                }

                // Check if there is anything we have "stacked up" on the other direction
                ReceiveTCPData(state, 1-direction);
            }

            return;
        }
Ejemplo n.º 4
0
        public void AnalysePacket(PacketInfo data)
        {
            byte [] PacketData = data.Data;
            int StartIndex = data.StartIndex;

            int Index = StartIndex;

            // Start by eliminating non IP and non TCP packets
            if( ( Index + LENGTH_OF_INTERNET + LENGTH_OF_TCP ) > PacketData.Length )
            {
                return ;
            }

            PacketINTERNET.PACKET_INTERNET PInternet = new PacketINTERNET.PACKET_INTERNET();
            PInternet.Version = PacketData[ Index++ ];
            PInternet.HeaderLength = (byte) ( ( (int) PInternet.Version & 0x0f ) * 4 );
            PInternet.Version = (byte) ( (int) PInternet.Version >> 4 );
            PInternet.DifferentiatedServicesField = PacketData[ Index++ ];
            PInternet.Length = Function.Get2Bytes( PacketData , ref Index , Const.NORMAL );
            PInternet.Identification = Function.Get2Bytes( PacketData , ref Index , Const.NORMAL );
            PInternet.FragmentOffset = Function.Get2Bytes( PacketData , ref Index , Const.NORMAL );
            PInternet.Flags = (byte)( (int) PInternet.FragmentOffset >> 12 );
            PInternet.FragmentOffset = (ushort) ( (int) PInternet.FragmentOffset & 0x0f );
            PInternet.TimeToLive = PacketData[ Index++ ];
            PInternet.Protocol = PacketData[ Index++ ];
            PInternet.HeaderChecksum = Function.Get2Bytes( PacketData , ref Index , Const.NORMAL );
            PInternet.Source = Function.GetIpAddress( PacketData , ref Index );
            PInternet.Destination  = Function.GetIpAddress( PacketData , ref Index );
            if(PInternet.Protocol  != IPPROTO_TCP )
                return;

            // Check IPs
            //if(!analysisFromCapFile)
            //{
                if(((PInternet.Source == IP1) && (PInternet.Destination == IP1)) ||
                    (PInternet.Source == PInternet.Destination))
                {
                    return;
                }
            //}

            PacketTCP.PACKET_TCP PTcp = new PacketTCP.PACKET_TCP();

            PTcp.SourcePort = Function.Get2Bytes( PacketData , ref Index , Const.NORMAL );
            PTcp.DestinationPort = Function.Get2Bytes( PacketData , ref Index , Const.NORMAL );
            PTcp.SequenceNumber = Function.Get4Bytes( PacketData , ref Index , Const.NORMAL );
            PTcp.Acknowledgement = Function.Get4Bytes( PacketData , ref Index , Const.NORMAL );
            PTcp.HeaderLength = PacketData[ Index++ ];
            PTcp.HeaderLength = (byte) ( ( (int) PTcp.HeaderLength >> 4 ) * 4 );
            PTcp.Flags = PacketData[ Index++ ];
            PTcp.WindowSize = Function.Get2Bytes( PacketData , ref Index , Const.NORMAL );
            PTcp.Checksum = Function.Get2Bytes( PacketData , ref Index , Const.NORMAL );
            PTcp.Options = Function.Get2Bytes( PacketData , ref Index , Const.NORMAL );

            //if(!analysisFromCapFile)
            //{
                if(((PTcp.SourcePort == Port1) && (PTcp.DestinationPort == Port1)) ||
                    ((PTcp.SourcePort == Port2) && (PTcp.DestinationPort == Port2)))
                {
                    return;
                }
            //}

            String signature = Signature(PInternet.Source, PTcp.SourcePort, PInternet.Destination, PTcp.DestinationPort);
            //Keep track of the connections which have been established.(The list will be used later to populate the Associations Combo Box.)
            if (!listOfConnections.Contains(signature))
            {
                listOfConnections.Add(signature);
            }
            TCPPacket packet = new TCPPacket(PacketData, StartIndex , PInternet, PTcp, data.TimeStamp);

            LastParsedPacketTime = packet.TimeStamp;

            int match = -1;
            TCPState state;
            for(int i=0;i<2;i++)
            {
                if(List[i].Contains(signature))
                {
                    match=i;
                }
            }

            // add as new item if necessary
            if(match==(-1))
            {
                //Need to check here that we have SYNs
                String signature1 = Signature(PInternet.Destination, PTcp.DestinationPort,PInternet.Source, PTcp.SourcePort);
                state = new TCPState(packet,signature, signature1);
                List[0].Add(signature,state);
                List[1].Add(signature1,state);
                match=0;
            }
            else
            {
                state = (TCPState) List[match][signature];
            }

            lock(state)
            {
                if(state.State[match] != TCPState.States.REPORTED)
                {
                    state.AddPacket(match,packet);
                    TCPState.PacketAction LastAction;
                    while((LastAction = state.Defragment(match)) == TCPState.PacketAction.DATA)
                    {
                        if(FragmentAdded != null)
                        {
                            FragmentAdded(state, match);
                        }
                        nrOfCapturedPackets++;
                    }
                    if(LastAction == TCPState.PacketAction.FIN)
                    {
                        if(EndOfStream != null)
                            EndOfStream(state, match, "FIN Seen (" + signature + ")");
                    }
                    if(LastAction == TCPState.PacketAction.RST)
                    {
                        if(EndOfStream != null)
                            EndOfStream(state, match, "RST Seen (" + signature + ")");
                    }
                    if(LastAction == TCPState.PacketAction.DEAD)
                    {
                        //Error("DEAD seen" + signature);
                        if(EndOfStream != null)
                            EndOfStream(state, match, "DEAD data seen (" + signature + ")");
                    }
                }
            }
        }
Ejemplo n.º 5
0
        public void AnalysePacket(PacketInfo data)
        {
            byte [] PacketData = data.Data;
            int     StartIndex = data.StartIndex;

            int Index = StartIndex;

            // Start by eliminating non IP and non TCP packets
            if ((Index + LENGTH_OF_INTERNET + LENGTH_OF_TCP) > PacketData.Length)
            {
                return;
            }

            PacketINTERNET.PACKET_INTERNET PInternet = new PacketINTERNET.PACKET_INTERNET();
            PInternet.Version      = PacketData[Index++];
            PInternet.HeaderLength = (byte)(((int)PInternet.Version & 0x0f) * 4);
            PInternet.Version      = (byte)((int)PInternet.Version >> 4);
            PInternet.DifferentiatedServicesField = PacketData[Index++];
            PInternet.Length         = Function.Get2Bytes(PacketData, ref Index, Const.NORMAL);
            PInternet.Identification = Function.Get2Bytes(PacketData, ref Index, Const.NORMAL);
            PInternet.FragmentOffset = Function.Get2Bytes(PacketData, ref Index, Const.NORMAL);
            PInternet.Flags          = (byte)((int)PInternet.FragmentOffset >> 12);
            PInternet.FragmentOffset = (ushort)((int)PInternet.FragmentOffset & 0x0f);
            PInternet.TimeToLive     = PacketData[Index++];
            PInternet.Protocol       = PacketData[Index++];
            PInternet.HeaderChecksum = Function.Get2Bytes(PacketData, ref Index, Const.NORMAL);
            PInternet.Source         = Function.GetIpAddress(PacketData, ref Index);
            PInternet.Destination    = Function.GetIpAddress(PacketData, ref Index);
            if (PInternet.Protocol != IPPROTO_TCP)
            {
                return;
            }

            // Check IPs
            //if(!analysisFromCapFile)
            //{
            if (((PInternet.Source == IP1) && (PInternet.Destination == IP1)) ||
                (PInternet.Source == PInternet.Destination))
            {
                return;
            }
            //}

            PacketTCP.PACKET_TCP PTcp = new PacketTCP.PACKET_TCP();

            PTcp.SourcePort      = Function.Get2Bytes(PacketData, ref Index, Const.NORMAL);
            PTcp.DestinationPort = Function.Get2Bytes(PacketData, ref Index, Const.NORMAL);
            PTcp.SequenceNumber  = Function.Get4Bytes(PacketData, ref Index, Const.NORMAL);
            PTcp.Acknowledgement = Function.Get4Bytes(PacketData, ref Index, Const.NORMAL);
            PTcp.HeaderLength    = PacketData[Index++];
            PTcp.HeaderLength    = (byte)(((int)PTcp.HeaderLength >> 4) * 4);
            PTcp.Flags           = PacketData[Index++];
            PTcp.WindowSize      = Function.Get2Bytes(PacketData, ref Index, Const.NORMAL);
            PTcp.Checksum        = Function.Get2Bytes(PacketData, ref Index, Const.NORMAL);
            PTcp.Options         = Function.Get2Bytes(PacketData, ref Index, Const.NORMAL);

            //if(!analysisFromCapFile)
            //{
            if (((PTcp.SourcePort == Port1) && (PTcp.DestinationPort == Port1)) ||
                ((PTcp.SourcePort == Port2) && (PTcp.DestinationPort == Port2)))
            {
                return;
            }
            //}

            String signature = Signature(PInternet.Source, PTcp.SourcePort, PInternet.Destination, PTcp.DestinationPort);

            //Keep track of the connections which have been established.(The list will be used later to populate the Associations Combo Box.)
            if (!listOfConnections.Contains(signature))
            {
                listOfConnections.Add(signature);
            }
            TCPPacket packet = new TCPPacket(PacketData, StartIndex, PInternet, PTcp, data.TimeStamp);

            LastParsedPacketTime = packet.TimeStamp;

            int      match = -1;
            TCPState state;

            for (int i = 0; i < 2; i++)
            {
                if (List[i].Contains(signature))
                {
                    match = i;
                }
            }

            // add as new item if necessary
            if (match == (-1))
            {
                //Need to check here that we have SYNs
                String signature1 = Signature(PInternet.Destination, PTcp.DestinationPort, PInternet.Source, PTcp.SourcePort);
                state = new TCPState(packet, signature, signature1);
                List[0].Add(signature, state);
                List[1].Add(signature1, state);
                match = 0;
            }
            else
            {
                state = (TCPState)List[match][signature];
            }

            lock (state)
            {
                if (state.State[match] != TCPState.States.REPORTED)
                {
                    state.AddPacket(match, packet);
                    TCPState.PacketAction LastAction;
                    while ((LastAction = state.Defragment(match)) == TCPState.PacketAction.DATA)
                    {
                        if (FragmentAdded != null)
                        {
                            FragmentAdded(state, match);
                        }
                        nrOfCapturedPackets++;
                    }
                    if (LastAction == TCPState.PacketAction.FIN)
                    {
                        if (EndOfStream != null)
                        {
                            EndOfStream(state, match, "FIN Seen (" + signature + ")");
                        }
                    }
                    if (LastAction == TCPState.PacketAction.RST)
                    {
                        if (EndOfStream != null)
                        {
                            EndOfStream(state, match, "RST Seen (" + signature + ")");
                        }
                    }
                    if (LastAction == TCPState.PacketAction.DEAD)
                    {
                        //Error("DEAD seen" + signature);
                        if (EndOfStream != null)
                        {
                            EndOfStream(state, match, "DEAD data seen (" + signature + ")");
                        }
                    }
                }
            }
        }
Ejemplo n.º 6
0
        public Association(TCPState state, String filename, System.DateTime time)
        {
            State = state;
            BaseFileName = filename;
            startTimeForAssoc = time;
            textLog= File.CreateText(BaseFileName + ".log");

            //Load SOP Class & Transfer Syntax maps
            sopClassMap = new SOPClassMap();
            tsMap = new TransferSyntaxMap();
        }
Ejemplo n.º 7
0
        /// <summary>
        /// This is the main routine called from DICOM Analyzer layer for handling each PDU
        /// </summary>
        /// <param name="p"></param>
        /// <param name="Position"></param>
        /// <param name="length"></param>
        /// <param name="direction"></param>
        /// <param name="state"></param>
        public void HandlePDU(byte[] p, uint Position, uint length, int direction, TCPState state)
        {
            byte PDUType = p[Position];
            uint Index = Position + 2;
            uint PDULength = DICOMUtility.Get4BytesBigEndian( p , ref Index);
            uint FinalPosition = Position + length +6 ;  // include length of PDU header
            StringBuilder s = new StringBuilder(500);
            System.DateTime dt1 = state.GetTime(direction,Position);
            System.DateTime dt2 = state.GetTime(direction,Position+length-1);

            int pduLength = (int)PDULength + 6;
            byte[] pduData = new byte[pduLength];
            Array.Copy(p,Position,pduData,0,pduLength);

            //Populate PDU list
            PDU_DETAIL pduDetail = new PDU_DETAIL();
            pduDetail.PduType = PDUType;
            pduDetail.PduDirection = direction;
            pduDetail.PduIndex = PDUNumber;
            pduDetail.PduData = pduData;
            pduDetail.PduLength = PDULength + 6; //include length of PDU header
            pduDetail.startTime = startTimeForAssoc;
            pduDetail.timeStamp = System.DateTime.Now;

            if(PDUType != 4)
            {
                pduList.Add(pduDetail);
            }

            DumpPDU(p, Position, BaseFileName, direction, PDULength,PDUNumber++);

            s.Append(string.Format("{0} Type {1} PDU : Length = {2} : Direction = {3}\r\n",state.Signature[direction],PDUType,PDULength,(direction==0)?"OUT":"IN"));
            s.Append(string.Format("{0:dd-MMM-yy HH:mm:ss.ffffff} to {1:HH:mm:ss.ffffff}\r\n",dt1,dt2));

            bool send = true;

            switch(PDUType)
            {
                case 1:
                case 2:
                {
                    isLastDatasetFragmentRecd = false;
                    isDataSetRecd = false;
                    HandleRequestPDU(s, p,Position+6, PDULength, direction,PDUType);
                    PopulateAssociationInfo(PDUType);
                    break;
                }
                case 3:
                    s.Append("Association Rejection\r\n");
                    break;

                case 4:
                {
                    if(PDULength==6)
                    {
                        s.Append("Illegal empty PDV\r\n");
                    }

                    isDataSetRecd = true;

                    Position +=6;
                    bool isCmdDataPDU = false;
                    while(Position < FinalPosition)
                    {
                        uint PDVLen = DICOMUtility.Get4BytesBigEndian(p, ref Position);
                        byte PCID = p[Position++];
                        byte Flags = p[Position++];

                        s.Append("  PDV Length=" + PDVLen.ToString() );
                        s.Append("  PCID = " + PCID.ToString());
                        s.Append("  Type = " + ((Flags & 0x01)>0?"COMMAND":"DATA"));
                        s.Append((Flags & 0x02)>0?"  Last Fragment\r\n":"  Continues...\r\n");
                        send = false;

                        byte[] thisData = new byte[PDVLen-2];
                        Array.Copy(p,Position,thisData,0,PDVLen-2);
                        ByteData[direction].Add(thisData);

                        //Add only Dataset data
                        if((Flags & 0x01)== 0)
                        {
                            DatasetData.Add(thisData);
                        }

                        if((Position + (PDVLen - 2)) == FinalPosition)
                        {
                            if((Flags & 0x01)== 0)
                            {
                                if(commandType != "")
                                {
                                    if(isCmdDataPDU)
                                        pduDetail.CmdType = commandType + "[Command,Data]";
                                    else
                                        pduDetail.CmdType = commandType + "[Data]";
                                }

                                cmdPdusList.Add(pduDetail);
                            }

                            if((Flags & 0x02)>0)  // Last fragment
                            {
                                if((Flags & 0x01)>0)
                                {
                                    s.Append(DICOMCommandDump(ByteData[direction]));
                                    if(commandType != "")
                                        pduDetail.CmdType = commandType + "[Command]";

                                    pduList.Add(pduDetail);
                                }
                                else
                                {
                                    foreach(PDU_DETAIL pdu in cmdPdusList)
                                    {
                                        pduDetail.CmdPdusList.Add(pdu);
                                    }
                                    pduDetail.CmdType = ((PDU_DETAIL)cmdPdusList[0]).CmdType;
                                    pduDetail.TransferSyntaxDataset = TransferSyntax[PCID];

                                    foreach(byte[] data in DatasetData)
                                    {
                                        pduDetail.ByteDataDump.Add(data);
                                    }
                                    pduList.Add(pduDetail);

                                    cmdPdusList.Clear();
                                    isLastDatasetFragmentRecd = true;
                                    s.Append(DICOMDump(ByteData[direction],TransferSyntax[PCID]));
                                }

                                ByteData[direction].Clear();
                                DatasetData.Clear();
                                send = true;
                            }
                        }
                        else
                        {
                            //PDU contains both Command & Data PDV
                            isCmdDataPDU = true;
                            if((Flags & 0x01)>0)
                            {
                                s.Append(DICOMCommandDump(ByteData[direction]));
                            }
                            else
                            {
                                s.Append(DICOMDump(ByteData[direction],TransferSyntax[PCID]));
                            }
                        }
                        Position += (PDVLen - 2);
                    }
                    break;
                }
                case 5:
                {
                    //Check for incomplete byte stream
                    if( isDataSetRecd && (!isLastDatasetFragmentRecd))
                    {
                        HandleIncompleteByteStream();
                    }
                    s.Append("Association Release Request\r\n");
                    break;
                }
                case 6:
                {
                    //Check for incomplete byte stream
                    if(isDataSetRecd && (!isLastDatasetFragmentRecd))
                    {
                        HandleIncompleteByteStream();
                    }
                    s.Append("Association Release Acceptance\r\n");
                    break;
                }
                case 7:
                {
                    s.Append("Association Abort\r\n");
                    break;
                }

                default:
                    s.Append("Unknown PDU Type\r\n");
                    break;
            }
            Out(s.ToString(),send);
            LastPDU = PDUType;
        }