public static KerberosData ProcessUDP(ConversationData c)
        {
            KerberosData KerbData = new KerberosData();

            KerbData.SourcePort = c.sourcePort;
            KerbData.convData   = c;

            int    Len2   = 0;
            int    TagLen = 0;
            string SPN    = null;
            int    TagID  = 0;

            bool IsContinueToNextFrame = false;

            foreach (FrameData fd in c.frames)
            {
                if (fd.payloadLength <= 1)
                {
                    continue;
                }


                TDSReader ByteReader = new TDSReader(fd.payload, 0, -1, fd.payloadLength);

                //Skip over 4 bytes 'ApplicationTag'
                ReadAsnLen(ByteReader);

                //Skip over 4 bytes 'KdcReq->SequenceHeader'
                ReadAsnLen(ByteReader);

                //Init vars after every frame processing

                Len2   = 0;
                TagLen = 0;
                SPN    = null;

                TagID = 0;

                do
                {
                    TagID  = ByteReader.ReadByte();
                    TagLen = ReadAsnLen(ByteReader, false);

                    TagID = TagID & 0x1F;
                    switch (TagID) //Lower 5 bits
                    {
                    case 0:        // version# in Tag 0 for KRB_TGS_REP (response)
                    case 1:
                    case 2:
                    {
                        if ((fd.isFromClient && TagID == 1) || (!fd.isFromClient && TagID == 0))
                        {
                            GetVersion(KerbData, ByteReader);
                        }
                        else if ((!fd.isFromClient && TagID == 1) || (fd.isFromClient && TagID == 2))
                        {
                            MessageTypes MsgType = GetMessageType(KerbData, ByteReader);
                            KerbData.frameNo = fd.frameNo;

                            if (MsgType == MessageTypes.KRB_TGS_REP)
                            {
                                //ParseNonErrorResponseUDP(KerbData, ByteReader);
                                IsContinueToNextFrame = true;
                            }
                            else if (MsgType == MessageTypes.KRB_ERROR)
                            {
                                ParseErrorResponseUDP(KerbData, ByteReader);
                                IsContinueToNextFrame = true;
                            }
                        }
                        break;
                    }

                    case 3:

                    {
                        //ByteReader.ReadByte();
                        Len2 = ReadAsnLen(ByteReader);
                        ByteReader.ReadBytes(Len2);         // skip the padata tag.
                        break;
                    }

                    case 4:
                    {
                        //ByteReader.ReadByte(); //skip sequence header of ReqBody
                        ReadAsnLen(ByteReader);
                        int TagId2 = 0;
                        do
                        {
                            TagId2 = ByteReader.ReadByte();
                            Len2   = ReadAsnLen(ByteReader, false);
                            TagId2 = TagId2 & 0x1F;
                            switch (TagId2)
                            {
                            case 0:
                            {
                                ByteReader.ReadByte();
                                int Len3 = ReadAsnLen(ByteReader, false);

                                //Read and skip 'padding'
                                ByteReader.ReadBytes(Len3 - 4);

                                KerbData.IsForwardable = (ByteReader.ReadByte() & 0x40) != 0;

                                //Read remaining three bytes
                                ByteReader.ReadBytes(3);
                                break;
                            }

                            case 1:
                            case 2:
                            case 4:
                            case 5:
                            case 7:
                            case 8:            //skip these tags.
                            {
                                ByteReader.ReadBytes(Len2);
                                break;
                            }

                            case 3:
                            {
                                // UDP SName implementation - replacing with TCP implementation

                                // ReadAsnLen(ByteReader);             //Skip sequence header  of sname
                                // int Len3 = ReadAsnLen(ByteReader);  //Skip Tag0  of sname
                                // ByteReader.ReadBytes(Len3);         //skip nametype
                                // ReadAsnLen(ByteReader);             //Skip  Tag1 of sname
                                // Len3 = ReadAsnLen(ByteReader);      //Skip sequence header  of sname->Tag1
                                // Len3 = ReadAsnLen(ByteReader);      // Read SPN Length - same as the TCP implementation
                                // SPN = ByteReader.ReadAnsiString(Len3);
                                // KerbData.SPNRequested = SPN;

                                // TCP SName implementation

                                ReadAsnLen(ByteReader);                 //Skip sequence header  of sname
                                int Len3 = ReadAsnLen(ByteReader);      //Skip Tag0  of sname
                                //
                                // Read the Name Type:
                                //
                                //  2 = NT-SRV-INST   - has two Strings: Service and Instance. '/' separater is implied
                                // 10 = NT-ENTERPRISE - has one String
                                //
                                // Throw error on all other values
                                //
                                Len3 = ReadAsnLen(ByteReader);
                                if (Len3 != 1)
                                {
                                    throw new Exception("Unexpected length (" + Len3 + ") reading SName Name Type.");
                                }
                                byte NameType = ByteReader.ReadByte();
                                KerbData.SNameType = NameType;
                                if (NameType != 2 && NameType != 10)
                                {
                                    IsContinueToNextFrame = true;
                                    break;
                                }

                                ReadAsnLen(ByteReader);                 //Skip  Tag1 of sname
                                Len3 = ReadAsnLen(ByteReader);          //Skip sequenceheader  of sname.

                                SPN = "";
                                if (NameType == 2)                 // read service type
                                {
                                    Len3 = ReadAsnLen(ByteReader);
                                    SPN  = ByteReader.ReadAnsiString(Len3) + "/";
                                }
                                Len3 = ReadAsnLen(ByteReader);                 // read SPN length
                                SPN += ByteReader.ReadAnsiString(Len3);
                                KerbData.SPNRequested = SPN;

                                break;
                            }

                            default:
                            {
                                throw new Exception("Unknonw tag in kerberos packet");
                            }
                            }
                        } while (TagId2 < 3);

                        break;
                    }

                    default:
                    {
                        // throw new Exception("Un expected tags in kerberos request/response/ problem in parseing");
                        break;
                    }
                    }
                }while ((TagID < 4) && (!IsContinueToNextFrame));
            }

            return(KerbData);
        }
        public static void ProcessUDP(NetworkTrace trace)
        {
            string[] DnsReturnMessage = new string[] {
                "Success",
                "Format error; DNS server did not understand the update request.",
                "DNS server encountered an internal error, such as a forwarding timeout.",
                "A name that should exist does not exist.",
                "DNS server does not support the specified Operation code.",
                "DNS server refuses to perform the update.",
                "A name that should not exist does exist.",
                "A resource record set that should not exist does exist.",
                "A resource record set that should exist does not exist.",
                "DNS server is not authoritative for the zone named in the Zone section.",
                "A name used in the Prerequisite or Update sections is not within the zone specified by the Zone section.",
                "Invalid return code.",
                "Invalid return code.",
                "Invalid return code.",
                "Invalid return code.",
                "Reserved."
            };

            foreach (ConversationData c in trace.conversations)
            {
                //DNS traffic is over UDP. If the current converstion is not UDP then skip that non DNS conversation.
                if (!c.isUDP)
                {
                    continue;
                }

                //Skip the conversation, if  its just UDP, but not DNS
                if ((c.isUDP) && c.destPort != 53)
                {
                    continue;
                }

                trace.DNSRequestCount++;

                try
                {
                    //Parse the DNS frames of the conversation.
                    foreach (FrameData fd in c.frames)
                    {
                        DNS DNSresponse = new DNS();

                        if (fd.payloadLength < 1)
                        {
                            continue;
                        }



                        //DNS data starts at 42nd byte of the total payload. so the payload = (Total Payload - 42) bytes.
                        TDSReader ByteReader = new TDSReader(fd.payload, 0, -1, fd.payloadLength);


                        ByteReader.ReadBigEndianUInt16();     //Skip over the query ID.

                        //Read the Flags and convert into bytes.
                        int FlagsHigh = ByteReader.ReadByte();
                        int FlagsLow  = ByteReader.ReadByte();

                        if ((FlagsHigh & (int)0x80) == (int)0x0)     // DNS request
                        {
                            //DNSresponse.srcServerIP  = c.sourceIP.ToString();
                            DNSresponse.dnsServerIP = c.destIP.ToString();
                        }
                        else if ((FlagsHigh & (int)0x80) == (int)0x80) // DNS response
                        {
                            int rCode = FlagsLow & 0x0F;               // should be between 0 - 15.

                            //DNSresponse.srcServerIP= c.destIP.ToString();
                            DNSresponse.dnsServerIP = c.sourceIP.ToString();
                            DNSresponse.frameNo     = fd.frameNo;
                            DNSresponse.TimeStamp   = new DateTime(((FrameData)c.frames[c.frames.Count - 1]).ticks).ToString(utility.TIME_FORMAT);
                            //new DateTime(((FrameData)trace.frames[0]).ticks).ToString(utility.TIME_FORMAT);
                            DNSresponse.errorCode = rCode;
                            DNSresponse.ErrorDesc = DnsReturnMessage[rCode];

                            //Question Count  - 2 bytes
                            DNSresponse.QuestionCount = ByteReader.ReadInt16();

                            //Answer Count - 2 bytes
                            DNSresponse.AnswerCount = ByteReader.ReadInt16();

                            //Skip 2 bytes - Name Server count
                            ByteReader.ReadInt16();

                            //Skip 2 bytes - Additional count
                            ByteReader.ReadInt16();

                            //Start reading the QName
                            //13th byte of the DNS Payload - payload[12]
                            byte   length = ByteReader.ReadByte();
                            string Name   = "";
                            while (length != 0)
                            {
                                Name  += (Name == "" ? "" : ".") + ByteReader.ReadAnsiString(length);
                                length = ByteReader.ReadByte();
                            }

                            DNSresponse.nameReqested = Name;
                            DNSresponse.convData     = c;
                            //DNSresponse.srcPort = c.sourcePort;

                            // Console.WriteLine(fd.file.filePath + "\t" + fd.frameNo.ToString());
                            if (rCode != (int)DNSReturnCodes.NOERROR)
                            {
                                trace.DNSResponses.Add(DNSresponse);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error parsing DNS conversation: " + ex.Message + "\r\n" + ex.StackTrace);
                    Program.logDiagnostic("Error parsing DNS conversation: " + ex.Message + "\r\n" + ex.StackTrace);
                }
            }
        }