Beispiel #1
0
        private void updateTree()
        {
            treeView_ParsedData.Nodes.Clear();

            if (listView_Packets.SelectedIndices.Count > 0)
            {
                PacketRecord record = records[Int32.Parse(listItems[listView_Packets.SelectedIndices[0]].SubItems[0].Text)];

                foreach (BlobFrag frag in record.netPacket.fragList_)
                {
                    BinaryReader fragDataReader = new BinaryReader(new MemoryStream(frag.dat_));
                    try
                    {
                        bool handled = false;
                        foreach (MessageProcessor messageProcessor in messageProcessors)
                        {
                            long readerStartPos = fragDataReader.BaseStream.Position;

                            bool accepted = messageProcessor.acceptMessageData(fragDataReader, treeView_ParsedData);

                            if (accepted && handled)
                            {
                                throw new Exception("Multiple message processors are handling the same data!");
                            }

                            if (accepted)
                            {
                                handled = true;
                                if (fragDataReader.BaseStream.Position != fragDataReader.BaseStream.Length)
                                {
                                    treeView_ParsedData.Nodes.Add(new TreeNode("WARNING: Prev fragment not fully read!"));
                                }
                            }

                            fragDataReader.BaseStream.Position = readerStartPos;
                        }

                        if (!handled)
                        {
                            PacketOpcode opcode = Util.readOpcode(fragDataReader);
                            treeView_ParsedData.Nodes.Add(new TreeNode("Unhandled: " + opcode));
                        }
                    }
                    catch (Exception e)
                    {
                        treeView_ParsedData.Nodes.Add(new TreeNode("EXCEPTION: " + e.Message));
                    }
                }
            }
        }
Beispiel #2
0
        private static bool addPacketIfFinished(List <PacketRecord> finishedRecords, PacketRecord record)
        {
            record.frags.Sort(new FragNumComparer());

            // Make sure all fragments are present
            if (record.frags.Count < record.frags[0].memberHeader_.numFrags ||
                record.frags[0].memberHeader_.blobNum != 0 ||
                record.frags[record.frags.Count - 1].memberHeader_.blobNum != record.frags[0].memberHeader_.numFrags - 1)
            {
                return(false);
            }

            record.index = finishedRecords.Count;

            // Remove duplicate fragments
            int index = 0;

            while (index < record.frags.Count - 1)
            {
                if (record.frags[index].memberHeader_.blobNum == record.frags[index + 1].memberHeader_.blobNum)
                {
                    record.frags.RemoveAt(index);
                }
                else
                {
                    index++;
                }
            }

            int totalMessageSize = 0;

            foreach (BlobFrag frag in record.frags)
            {
                totalMessageSize += frag.dat_.Length;
            }

            record.data = new byte[totalMessageSize];
            int offset = 0;

            foreach (BlobFrag frag in record.frags)
            {
                Buffer.BlockCopy(frag.dat_, 0, record.data, offset, frag.dat_.Length);
                offset += frag.dat_.Length;
            }

            finishedRecords.Add(record);

            return(true);
        }
Beispiel #3
0
        public static void CopyACETelelocToClipboard(PacketRecord record)
        {
            try
            {
                using (BinaryReader fragDataReader = new BinaryReader(new MemoryStream(record.data)))
                {
                    var messageCode = fragDataReader.ReadUInt32();
                    if (messageCode == 0xF7B1)                      // Game Action
                    {
                        var sequence = fragDataReader.ReadUInt32(); // Sequence
                        messageCode = fragDataReader.ReadUInt32();  // Event
                    }
                    string telelocLine;

                    if (messageCode == (int)PacketOpcode.Evt_Physics__CreateObject_ID)
                    {
                        var parsed = CM_Physics.CreateObject.read(fragDataReader);
                        if ((parsed.physicsdesc.bitfield & (uint)CM_Physics.PhysicsDesc.PhysicsDescInfo.POSITION) != 0)
                        {
                            telelocLine = GetTelelocString(parsed.physicsdesc.pos);
                        }
                        else
                        {
                            throw new Exception("This message does not contain a position.");
                        }
                    }
                    else if (messageCode == (int)PacketOpcode.Evt_Movement__UpdatePosition_ID)
                    {
                        var parsed = CM_Movement.UpdatePosition.read(fragDataReader);
                        telelocLine = GetTelelocString(parsed.positionPack.position);
                    }
                    else if (messageCode == (int)PacketOpcode.Evt_Movement__MoveToState_ID)
                    {
                        var parsed = CM_Movement.MoveToState.read(fragDataReader);
                        telelocLine = GetTelelocString(parsed.position);
                    }
                    else
                    {
                        throw new Exception();
                    }
                    Clipboard.SetText(telelocLine);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Could not copy @teleloc line.\n{ex.Message}", "Error:", MessageBoxButtons.OK,
                                MessageBoxIcon.Error);
            }
        }
        private int SearchForText(PacketRecord record, string textToSearch, bool caseSensitive = true)
        {
            int exceptions = 0;
            int hits       = 0;

            try
            {
                if (record.data.Length <= 4)
                {
                    return(hits);
                }

                //BinaryReader fragDataReader = new BinaryReader(new MemoryStream(record.data));

                if (caseSensitive)
                {
                    int asciiResult   = SearchBytePattern(ASCIIEncoding.ASCII.GetBytes(textToSearch), record.data);
                    int unicodeResult = SearchBytePattern(UnicodeEncoding.Unicode.GetBytes(textToSearch), record.data);
                    if (asciiResult > 0 || unicodeResult > 0)
                    {
                        hits++;
                    }
                }
                else
                {
                    string asciiStringData   = System.Text.Encoding.ASCII.GetString(record.data);
                    string unicodeStringData = System.Text.Encoding.Unicode.GetString(record.data);
                    // Shift the byte stream by 1 to catch any Unicode strings not on the previous two byte boundary
                    string unicodeStringData2 = System.Text.Encoding.Unicode.GetString(record.data, 1, record.data.Length - 1);                    //(int)fragDataReader.BaseStream.Length - 1);
                    int    asciiResultCI      = asciiStringData.IndexOf(textToSearch, StringComparison.OrdinalIgnoreCase);
                    int    unicodeResultCI    = unicodeStringData.IndexOf(textToSearch, StringComparison.OrdinalIgnoreCase);
                    int    unicodeResultCI2   = unicodeStringData2.IndexOf(textToSearch, StringComparison.OrdinalIgnoreCase);
                    if (asciiResultCI != -1 || unicodeResultCI != -1 || unicodeResultCI2 != -1)
                    {
                        hits++;
                    }
                }
            }
            catch
            {
                // Do something with the exception maybe
                exceptions++;

                //Interlocked.Increment(ref totalExceptions);
            }
            return(hits);
        }
        private void readPacket(PacketRecord packet, StringBuilder packetTypeStr, BinaryReader packetReader)
        {
            BlobFrag newFrag = new BlobFrag();

            newFrag.memberHeader_ = BlobFragHeader_t.read(packetReader);
            newFrag.dat_          = packetReader.ReadBytes(newFrag.memberHeader_.blobFragSize - 16); // 16 == size of frag header

            packet.netPacket.fragList_.Add(newFrag);

            BinaryReader fragDataReader = new BinaryReader(new MemoryStream(newFrag.dat_));

            if (newFrag.memberHeader_.blobNum != 0)
            {
                packetTypeStr.Append("FragData[");
                packetTypeStr.Append(newFrag.memberHeader_.blobNum);
                packetTypeStr.Append("]");
            }
            else
            {
                PacketOpcode opcode = Util.readOpcode(fragDataReader);
                packet.opcodes.Add(opcode);
                packetTypeStr.Append(opcode.ToString());
            }
        }
Beispiel #6
0
        private static bool readMessageData(BinaryReader binaryReader, long len, uint tsSec, List <PacketRecord> results, Dictionary <ulong, PacketRecord> incompletePacketMap)
        {
            // Begin reading headers
            long packetStartPos = binaryReader.BaseStream.Position;

            bool isSend = readNetworkHeaders(binaryReader);

            long headersSize = binaryReader.BaseStream.Position - packetStartPos;

            // Begin reading non-header packet content
            StringBuilder packetHeadersStr = new StringBuilder();
            StringBuilder packetTypeStr    = new StringBuilder();

            PacketRecord packet = null;

            byte[]       packetData   = binaryReader.ReadBytes((int)(len - headersSize));
            BinaryReader packetReader = new BinaryReader(new MemoryStream(packetData));

            try
            {
                ProtoHeader pHeader = ProtoHeader.read(packetReader);

                uint HAS_FRAGS_MASK = 0x4; // See SharedNet::SplitPacketData

                if ((pHeader.header_ & HAS_FRAGS_MASK) != 0)
                {
                    readOptionalHeaders(pHeader.header_, packetHeadersStr, packetReader);

                    while (packetReader.BaseStream.Position != packetReader.BaseStream.Length)
                    {
                        BlobFrag newFrag = readFragment(packetReader);

                        ulong blobID = newFrag.memberHeader_.blobID;
                        if (incompletePacketMap.ContainsKey(blobID))
                        {
                            packet = incompletePacketMap[newFrag.memberHeader_.blobID];
                        }
                        else
                        {
                            packet = new PacketRecord();
                            incompletePacketMap.Add(blobID, packet);
                        }

                        if (newFrag.memberHeader_.blobNum == 0)
                        {
                            packet.isSend    = isSend;
                            packet.tsSec     = tsSec;
                            packet.extraInfo = "";

                            BinaryReader fragDataReader = new BinaryReader(new MemoryStream(newFrag.dat_));
                            PacketOpcode opcode         = Util.readOpcode(fragDataReader);
                            packet.opcodes.Add(opcode);
                            packet.packetTypeStr = opcode.ToString();
                        }

                        packet.packetHeadersStr += packetHeadersStr.ToString();

                        packet.frags.Add(newFrag);

                        if (addPacketIfFinished(results, packet))
                        {
                            incompletePacketMap.Remove(blobID);
                        }
                    }

                    if (packetReader.BaseStream.Position != packetReader.BaseStream.Length)
                    {
                        packet.extraInfo = "Didnt read entire packet! " + packet.extraInfo;
                    }
                }
            }
            catch (OutOfMemoryException e)
            {
                //MessageBox.Show("Out of memory (packet " + curPacket + "), stopping read: " + e);
                return(false);
            }
            catch (Exception e)
            {
                packet.extraInfo += "EXCEPTION: " + e.Message + " " + e.StackTrace;
            }

            return(true);
        }
Beispiel #7
0
        private static PacketRecord readPacketData(BinaryReader binaryReader, long len, uint tsSec, int curPacket)
        {
            // Begin reading headers
            long packetStartPos = binaryReader.BaseStream.Position;

            bool isSend = readNetworkHeaders(binaryReader);

            long headersSize = binaryReader.BaseStream.Position - packetStartPos;

            // Begin reading non-header packet content
            StringBuilder packetHeadersStr = new StringBuilder();
            StringBuilder packetTypeStr    = new StringBuilder();

            PacketRecord packet = new PacketRecord();

            packet.index     = curPacket;
            packet.isSend    = isSend;
            packet.tsSec     = tsSec;
            packet.extraInfo = "";
            packet.data      = binaryReader.ReadBytes((int)(len - headersSize));
            BinaryReader packetReader = new BinaryReader(new MemoryStream(packet.data));

            try
            {
                ProtoHeader pHeader = ProtoHeader.read(packetReader);

                packet.optionalHeadersLen = readOptionalHeaders(pHeader.header_, packetHeadersStr, packetReader);

                if (packetReader.BaseStream.Position == packetReader.BaseStream.Length)
                {
                    packetTypeStr.Append("<Header Only>");
                }

                uint HAS_FRAGS_MASK = 0x4; // See SharedNet::SplitPacketData

                if ((pHeader.header_ & HAS_FRAGS_MASK) != 0)
                {
                    while (packetReader.BaseStream.Position != packetReader.BaseStream.Length)
                    {
                        if (packetTypeStr.Length != 0)
                        {
                            packetTypeStr.Append(" + ");
                        }

                        BlobFrag newFrag = readFragment(packetReader);
                        packet.frags.Add(newFrag);

                        if (newFrag.memberHeader_.blobNum != 0)
                        {
                            packetTypeStr.Append("FragData[");
                            packetTypeStr.Append(newFrag.memberHeader_.blobNum);
                            packetTypeStr.Append("]");
                        }
                        else
                        {
                            BinaryReader fragDataReader = new BinaryReader(new MemoryStream(newFrag.dat_));
                            PacketOpcode opcode         = Util.readOpcode(fragDataReader);
                            packet.opcodes.Add(opcode);
                            packetTypeStr.Append(opcode);
                        }
                    }
                }

                if (packetReader.BaseStream.Position != packetReader.BaseStream.Length)
                {
                    packet.extraInfo = "Didnt read entire packet! " + packet.extraInfo;
                }
            }
            catch (OutOfMemoryException e)
            {
                //MessageBox.Show("Out of memory (packet " + curPacket + "), stopping read: " + e);
                return(null);
            }
            catch (Exception e)
            {
                packet.extraInfo += "EXCEPTION: " + e.Message + " " + e.StackTrace;
            }

            packet.packetHeadersStr = packetHeadersStr.ToString();
            packet.packetTypeStr    = packetTypeStr.ToString();

            return(packet);
        }
Beispiel #8
0
        private void menuItem_ToolBad_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog openFolder = new FolderBrowserDialog();

            if (openFolder.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            List <string> files = new List <string>();

            files.AddRange(Directory.GetFiles(openFolder.SelectedPath, "*.pcap", SearchOption.AllDirectories));
            files.AddRange(Directory.GetFiles(openFolder.SelectedPath, "*.pcapng", SearchOption.AllDirectories));

            OrderedDictionary opcodeOccurrences = new OrderedDictionary();

            foreach (PacketOpcode opcode in Enum.GetValues(typeof(PacketOpcode)))
            {
                opcodeOccurrences[opcode] = 0;
            }

            foreach (string file in files)
            {
                loadPcap(file, false);

                int curPacket   = 0;
                int curFragment = 0;
                try
                {
                    for (curPacket = 0; curPacket < records.Count; ++curPacket)
                    {
                        PacketRecord record = records[curPacket];
                        for (curFragment = 0; curFragment < record.frags.Count; ++curFragment)
                        {
                            BlobFrag frag = record.frags[curFragment];
                            if (frag.memberHeader_.numFrags > 0)
                            {
                                continue;
                            }

                            BinaryReader fragDataReader = new BinaryReader(new MemoryStream(frag.dat_));

                            bool handled = false;
                            foreach (MessageProcessor messageProcessor in messageProcessors)
                            {
                                long readerStartPos = fragDataReader.BaseStream.Position;

                                bool accepted = messageProcessor.acceptMessageData(fragDataReader, treeView_ParsedData);

                                if (accepted && handled)
                                {
                                    throw new Exception("Multiple message processors are handling the same data!");
                                }

                                if (accepted)
                                {
                                    handled = true;
                                }

                                fragDataReader.BaseStream.Position = readerStartPos;
                            }

                            /*if (!handled) {
                             *  PacketOpcode opcode = Util.readOpcode(fragDataReader);
                             *  treeView_ParsedData.Nodes.Add(new TreeNode("Unhandled: " + opcode));
                             * }*/
                        }
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Packet " + curPacket + " Fragment " + curFragment + " EXCEPTION: " + ex.Message);
                    break;
                }
            }
        }
Beispiel #9
0
        private void updateText()
        {
            textBox_PacketData.Clear();

            if (listView_Packets.SelectedIndices.Count > 0)
            {
                PacketRecord record = records[Int32.Parse(listItems[listView_Packets.SelectedIndices[0]].SubItems[0].Text)];
                byte[]       data   = record.data;

                if (checkBox_useHighlighting.Checked && !loadedAsMessages)
                {
                    int fragStartPos = 20 + record.optionalHeadersLen;
                    int curFrag      = 0;
                    int curLine      = 0;
                    int dataConsumed = 0;
                    while (dataConsumed < data.Length)
                    {
                        textBox_PacketData.SelectionColor = Color.Black;
                        textBox_PacketData.AppendText(string.Format("{0:X4}  ", curLine));

                        int lineFragStartPos = fragStartPos;
                        int linecurFrag      = curFrag;

                        int hexIndex = 0;
                        for (; hexIndex < Math.Min(16, data.Length - dataConsumed); ++hexIndex)
                        {
                            if (hexIndex == 8)
                            {
                                textBox_PacketData.AppendText(" ");
                            }

                            int dataIndex = dataConsumed + hexIndex;

                            int      selectedIndex = -1;
                            TreeNode selectedNode  = treeView_ParsedData.SelectedNode;
                            if (selectedNode != null)
                            {
                                while (selectedNode.Parent != null)
                                {
                                    selectedNode = selectedNode.Parent;
                                }
                                selectedIndex = selectedNode.Index;
                            }

                            // Default color
                            textBox_PacketData.SelectionColor     = Color.Red;
                            textBox_PacketData.SelectionBackColor = Color.White;

                            if (dataIndex < 20)
                            {
                                // Protocol header
                                textBox_PacketData.SelectionColor = Color.Blue;
                            }
                            else if (dataIndex < 20 + record.optionalHeadersLen)
                            {
                                // Optional headers
                                textBox_PacketData.SelectionColor = Color.Green;
                            }
                            else if (record.frags.Count > 0)
                            {
                                if (curFrag < record.frags.Count)
                                {
                                    int fragCurPos = dataIndex - fragStartPos;
                                    if (fragCurPos < 16)
                                    {
                                        // Fragment header
                                        textBox_PacketData.SelectionColor = Color.Magenta;
                                    }
                                    else if (fragCurPos == (16 + record.frags[curFrag].dat_.Length))
                                    {
                                        // Next fragment
                                        fragStartPos = dataIndex;
                                        curFrag++;
                                        textBox_PacketData.SelectionColor = Color.Magenta;
                                    }
                                    else
                                    {
                                        // Fragment data
                                        textBox_PacketData.SelectionColor = Color.Black;
                                    }

                                    if (selectedIndex == curFrag)
                                    {
                                        textBox_PacketData.SelectionBackColor = Color.LightGray;
                                    }
                                }
                            }

                            textBox_PacketData.AppendText(string.Format("{0:X2} ", data[dataIndex]));
                        }

                        textBox_PacketData.SelectionBackColor = Color.White;
                        StringBuilder spaceAligner = new StringBuilder();
                        spaceAligner.Append(' ', 1 + (16 - hexIndex) * 3 + (hexIndex <= 8 ? 1 : 0));
                        textBox_PacketData.AppendText(spaceAligner.ToString());

                        fragStartPos = lineFragStartPos;
                        curFrag      = linecurFrag;

                        for (int i = 0; i < Math.Min(16, data.Length - dataConsumed); ++i)
                        {
                            if (i == 8)
                            {
                                textBox_PacketData.AppendText(" ");
                            }

                            int dataIndex = dataConsumed + i;

                            int      selectedIndex = -1;
                            TreeNode selectedNode  = treeView_ParsedData.SelectedNode;
                            if (selectedNode != null)
                            {
                                while (selectedNode.Parent != null)
                                {
                                    selectedNode = selectedNode.Parent;
                                }
                                selectedIndex = selectedNode.Index;
                            }

                            // Default color
                            textBox_PacketData.SelectionColor     = Color.Red;
                            textBox_PacketData.SelectionBackColor = Color.White;

                            if (dataIndex < 20)
                            {
                                // Protocol header
                                textBox_PacketData.SelectionColor = Color.Blue;
                            }
                            else if (dataIndex < 20 + record.optionalHeadersLen)
                            {
                                // Optional headers
                                textBox_PacketData.SelectionColor = Color.Green;
                            }
                            else if (record.frags.Count > 0)
                            {
                                if (curFrag < record.frags.Count)
                                {
                                    int fragCurPos = dataIndex - fragStartPos;
                                    if (fragCurPos < 16)
                                    {
                                        // Fragment header
                                        textBox_PacketData.SelectionColor = Color.Magenta;
                                    }
                                    else if (fragCurPos == (16 + record.frags[curFrag].dat_.Length))
                                    {
                                        // Next fragment
                                        fragStartPos = dataIndex;
                                        curFrag++;
                                        textBox_PacketData.SelectionColor = Color.Magenta;
                                    }
                                    else
                                    {
                                        // Fragment data
                                        textBox_PacketData.SelectionColor = Color.Black;
                                    }

                                    if (selectedIndex == curFrag)
                                    {
                                        textBox_PacketData.SelectionBackColor = Color.LightGray;
                                    }
                                }
                            }

                            char asChar = Convert.ToChar(data[dataIndex]);
                            if (asChar >= ' ' && asChar <= '~')
                            {
                                textBox_PacketData.AppendText(Char.ToString(asChar));
                            }
                            else
                            {
                                textBox_PacketData.AppendText(".");
                            }
                        }

                        textBox_PacketData.AppendText("\n");

                        dataConsumed += 16;
                        curLine++;
                    }
                }
                else
                {
                    StringBuilder strBuilder   = new StringBuilder();
                    StringBuilder hexBuilder   = new StringBuilder();
                    StringBuilder asciiBuilder = new StringBuilder();
                    int           wrapCounter  = 0;
                    for (int i = 0; i < data.Length; ++i)
                    {
                        if (wrapCounter == 0)
                        {
                            strBuilder.Append(string.Format("{0:X4}  ", i));
                        }

                        hexBuilder.Append(string.Format("{0:X2} ", data[i]));

                        char asChar = Convert.ToChar(data[i]);
                        if (asChar >= ' ' && asChar <= '~')
                        {
                            asciiBuilder.Append(asChar);
                        }
                        else
                        {
                            asciiBuilder.Append('.');
                        }

                        wrapCounter++;
                        if (wrapCounter == 8)
                        {
                            hexBuilder.Append(' ');
                            asciiBuilder.Append(' ');
                        }
                        else if (wrapCounter == 16)
                        {
                            strBuilder.Append(hexBuilder.ToString());
                            hexBuilder.Clear();

                            strBuilder.Append(' ');

                            strBuilder.Append(asciiBuilder.ToString());
                            asciiBuilder.Clear();

                            strBuilder.Append(Environment.NewLine);

                            wrapCounter = 0;
                        }
                    }

                    if (wrapCounter != 0)
                    {
                        int spacesToAppend = (16 - wrapCounter) * 3;
                        if (wrapCounter < 8)
                        {
                            spacesToAppend++;
                        }

                        hexBuilder.Append(' ', spacesToAppend);

                        strBuilder.Append(hexBuilder.ToString());

                        strBuilder.Append(' ');

                        strBuilder.Append(asciiBuilder.ToString());
                    }

                    textBox_PacketData.Text = strBuilder.ToString();
                }
            }
        }
        private int readPacketRecordData(BinaryReader binaryReader, long len, uint tsSec, long curPacket, bool dontList)
        {
            // Begin reading headers
            long packetStartPos = binaryReader.BaseStream.Position;

            EthernetHeader ethernetHeader = EthernetHeader.read(binaryReader);

            // Skip non-IP packets
            if (ethernetHeader.proto != 8)
            {
                binaryReader.BaseStream.Position += len - (binaryReader.BaseStream.Position - packetStartPos);
                return(1);
            }

            IpHeader ipHeader = IpHeader.read(binaryReader);

            // Skip non-UDP packets
            if (ipHeader.proto != 17)
            {
                binaryReader.BaseStream.Position += len - (binaryReader.BaseStream.Position - packetStartPos);
                return(1);
            }

            UdpHeader udpHeader = UdpHeader.read(binaryReader);

            bool isSend = (udpHeader.dPort >= 9000 && udpHeader.dPort <= 9013);
            bool isRecv = (udpHeader.sPort >= 9000 && udpHeader.sPort <= 9013);

            // Skip non-AC-port packets
            if (!isSend && !isRecv)
            {
                binaryReader.BaseStream.Position += len - (binaryReader.BaseStream.Position - packetStartPos);
                return(1);
            }

            long headersSize = binaryReader.BaseStream.Position - packetStartPos;

            // Begin reading non-header packet content
            StringBuilder packetHeadersStr = new StringBuilder();
            StringBuilder packetTypeStr    = new StringBuilder();

            PacketRecord packet = new PacketRecord();

            packet.index     = records.Count;
            packet.isSend    = isSend;
            packet.tsSec     = tsSec;
            packet.netPacket = new NetPacket();
            packet.data      = binaryReader.ReadBytes((int)(len - headersSize));
            packet.extraInfo = "";
            BinaryReader packetReader = new BinaryReader(new MemoryStream(packet.data));

            try {
                ProtoHeader pHeader = ProtoHeader.read(packetReader);

                readOptionalHeaders(packet, pHeader.header_, packetHeadersStr, packetReader);

                if (packetReader.BaseStream.Position == packetReader.BaseStream.Length)
                {
                    packetTypeStr.Append("<Header Only>");
                }

                uint HAS_FRAGS_MASK = 0x4; // See SharedNet::SplitPacketData
                if ((pHeader.header_ & HAS_FRAGS_MASK) != 0)
                {
                    bool first = true;
                    while (packetReader.BaseStream.Position != packetReader.BaseStream.Length)
                    {
                        if (!first)
                        {
                            packetTypeStr.Append(" + ");
                        }
                        readPacket(packet, packetTypeStr, packetReader);
                        first = false;
                    }
                }

                if (packetReader.BaseStream.Position != packetReader.BaseStream.Length)
                {
                    packet.extraInfo = "Didnt read entire packet! " + packet.extraInfo;
                }
            } catch (OutOfMemoryException e) {
                //MessageBox.Show("Out of memory (packet " + curPacket + "), stopping read: " + e);
                return(2);
            } catch (Exception e) {
                packet.extraInfo += "EXCEPTION: " + e.Message + " " + e.StackTrace;
            }
            packet.packetHeadersStr = packetHeadersStr.ToString();
            packet.packetTypeStr    = packetTypeStr.ToString();

            records.Add(packet);

            if (!dontList)
            {
                ListViewItem newItem = new ListViewItem(packet.index.ToString());
                newItem.SubItems.Add(packet.isSend ? "Send" : "Recv");
                newItem.SubItems.Add(packet.tsSec.ToString());
                newItem.SubItems.Add(packet.packetHeadersStr);
                newItem.SubItems.Add(packet.packetTypeStr);
                newItem.SubItems.Add(packet.data.Length.ToString());
                newItem.SubItems.Add(packet.extraInfo);
                listItems.Add(newItem);
            }

            return(0);
        }
        private void readOptionalHeaders(PacketRecord packet, uint header_, StringBuilder packetHeadersStr, BinaryReader packetReader)
        {
            long readStartPos = packetReader.BaseStream.Position;

            if ((header_ & CServerSwitchStructHeader.mask) != 0)
            {
                CServerSwitchStruct serverSwitchStruct = CServerSwitchStruct.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Server Switch");
            }

            if ((header_ & LogonServerAddrHeader.mask) != 0)
            {
                sockaddr_in serverAddr = sockaddr_in.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Logon Server Addr");
            }

            if ((header_ & CEmptyHeader1.mask) != 0)
            {
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Empty Header 1");
            }

            if ((header_ & CReferralStructHeader.mask) != 0)
            {
                CReferralStruct referralStruct = CReferralStruct.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Referral");
            }

            if ((header_ & NakHeader.mask) != 0)
            {
                CSeqIDListHeader nakSeqIDs = NakHeader.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Nak");
            }

            if ((header_ & EmptyAckHeader.mask) != 0)
            {
                CSeqIDListHeader ackSeqIDs = EmptyAckHeader.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Empty Ack");
            }

            if ((header_ & PakHeader.mask) != 0)
            {
                PakHeader pakHeader = PakHeader.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Pak");
            }

            if ((header_ & CEmptyHeader2.mask) != 0)
            {
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Empty Header 2");
            }

            if ((header_ & CLogonHeader.mask) != 0)
            {
                CLogonHeader.HandshakeWireData handshakeData = CLogonHeader.HandshakeWireData.read(packetReader);
                byte[] authData = packetReader.ReadBytes((int)handshakeData.cbAuthData);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Logon");
            }

            if ((header_ & ULongHeader.mask) != 0)
            {
                ULongHeader ulongHeader = ULongHeader.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("ULong 1");
            }

            if ((header_ & CConnectHeader.mask) != 0)
            {
                CConnectHeader.HandshakeWireData handshakeData = CConnectHeader.HandshakeWireData.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Connect");
            }

            if ((header_ & ULongHeader2.mask) != 0)
            {
                ULongHeader2 ulongHeader = ULongHeader2.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("ULong 2");
            }

            if ((header_ & NetErrorHeader.mask) != 0)
            {
                NetError netError = NetError.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Net Error");
            }

            if ((header_ & NetErrorHeader_cs_DisconnectReceived.mask) != 0)
            {
                NetError netError = NetError.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Net Error Disconnect");
            }

            if ((header_ & CICMDCommandStructHeader.mask) != 0)
            {
                CICMDCommandStruct icmdStruct = CICMDCommandStruct.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("ICmd");
            }

            if ((header_ & CTimeSyncHeader.mask) != 0)
            {
                CTimeSyncHeader timeSyncHeader = CTimeSyncHeader.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Time Sync");
            }

            if ((header_ & CEchoRequestHeader.mask) != 0)
            {
                CEchoRequestHeader echoRequestHeader = CEchoRequestHeader.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Echo Request");
            }

            if ((header_ & CEchoResponseHeader.mask) != 0)
            {
                CEchoResponseHeader.CEchoResponseHeaderWireData echoResponseData = CEchoResponseHeader.CEchoResponseHeaderWireData.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Echo Response");
            }

            if ((header_ & CFlowStructHeader.mask) != 0)
            {
                CFlowStruct flowStruct = CFlowStruct.read(packetReader);
                if (packetHeadersStr.Length != 0)
                {
                    packetHeadersStr.Append(" | ");
                }
                packetHeadersStr.Append("Flow");
            }

            packet.optionalHeadersLen = (int)(packetReader.BaseStream.Position - readStartPos);
        }