/// <summary>
        ///     Attempts to parse raw data into a structured packet
        /// </summary>
        /// <param name="buffer">Raw data to parse</param>
        /// <param name="packet">Parsed packet</param>
        /// <param name="count">The length of the packet in bytes</param>
        /// <param name="index">The index into the buffer at which the packet begins</param>
        /// <returns>True if parsing was successful, false if it is not.</returns>
        internal static bool TryParse(byte[] buffer, int index, int count, out EapolKey packet)
        {
            try
            {
                if (count < MinimumParseableBytes)
                {
                    packet = null;
                    return(false);
                }

                using (var ms = new MemoryStream(buffer, index, count, false))
                {
                    using (var br = new BinaryReader(ms))
                    {
                        packet = new EapolKey();
                        packet.KeyDescriptorType = br.ReadByte();
                        packet.KeyInformation    = ByteOrder.NetworkToHostOrder(br.ReadUInt16());
                        packet.KeyLength         = ByteOrder.NetworkToHostOrder(br.ReadUInt16());
                        packet.ReplayCounter     = br.ReadBytes(8);
                        packet.Nonce             = br.ReadBytes(32);
                        packet.IV      = br.ReadBytes(16);
                        packet.RSC     = br.ReadBytes(8);
                        packet.ID      = br.ReadBytes(8);
                        packet.MIC     = br.ReadBytes(16);
                        packet.DataLen = ByteOrder.NetworkToHostOrder(br.ReadUInt16());
                        packet.Data    = br.ReadBytes((int)(count - br.BaseStream.Position));

                        return(true);
                    }
                }
            }
            catch (Exception)
            {
                packet = null;
                return(false);
            }
        }
        /// <summary>
        ///     Attempts to parse raw data into a structured packet
        /// </summary>
        /// <param name="buffer">Raw data to parse</param>
        /// <param name="packet">Parsed packet</param>
        /// <param name="count">The length of the packet in bytes</param>
        /// <param name="index">The index into the buffer at which the packet begins</param>
        /// <returns>True if parsing was successful, false if it is not.</returns>
        internal static bool TryParse(byte[] buffer, int index, int count, out EapolKey packet)
        {
            try
            {
                if (count < MinimumParseableBytes)
                {
                    packet = null;
                    return false;
                }

                using (var ms = new MemoryStream(buffer, index, count, false))
                {
                    using (var br = new BinaryReader(ms))
                    {
                        packet = new EapolKey();
                        packet.KeyDescriptorType = br.ReadByte();
                        packet.KeyInformation = ByteOrder.NetworkToHostOrder(br.ReadUInt16());
                        packet.KeyLength = ByteOrder.NetworkToHostOrder(br.ReadUInt16());
                        packet.ReplayCounter = br.ReadBytes(8);
                        packet.Nonce = br.ReadBytes(32);
                        packet.IV = br.ReadBytes(16);
                        packet.RSC = br.ReadBytes(8);
                        packet.ID = br.ReadBytes(8);
                        packet.MIC = br.ReadBytes(16);
                        packet.DataLen = ByteOrder.NetworkToHostOrder(br.ReadUInt16());
                        packet.Data = br.ReadBytes((int)(count - br.BaseStream.Position));

                        return true;
                    }
                }
            }
            catch (Exception)
            {
                packet = null;
                return false;
            }
        }
        /// <summary>
        ///     Attempts to parse raw data into a structured packet
        /// </summary>
        /// <param name="buffer">Raw data to parse</param>
        /// <param name="packet">Parsed packet</param>
        /// <param name="count">The length of the packet in bytes</param>
        /// <param name="index">The index into the buffer at which the packet begins</param>
        /// <returns>True if parsing was successful, false if it is not.</returns>
        internal static bool TryParse(byte[] buffer, int index, int count, out IEEE802_1x packet)
        {
            try
            {
                if (count < MinimumParseableBytes)
                {
                    packet = null;
                    return(false);
                }

                using (var ms = new MemoryStream(buffer, index, count, false))
                {
                    using (var br = new BinaryReader(ms))
                    {
                        var version    = br.ReadByte();
                        var type       = br.ReadByte();
                        var bodyLength = ByteOrder.NetworkToHostOrder(br.ReadUInt16());

                        var payloadLength = Math.Min(bodyLength, (int)(count - br.BaseStream.Position));

                        packet = null;

                        switch (type)
                        {
                        case (byte)Types.EAPOL_KEY:
                        {
                            EapolKey payload;
                            if (EapolKey.TryParse(
                                    buffer,
                                    index + (int)br.BaseStream.Position,
                                    payloadLength,
                                    out payload))
                            {
                                packet = new IEEE802_1x <EapolKey> {
                                    Payload = payload
                                };
                            }
                        }
                        break;
                        }

                        if (packet == null)
                        {
                            Generic payload;
                            Generic.TryParse(
                                buffer,
                                index + (int)br.BaseStream.Position,
                                (int)(count - br.BaseStream.Position),
                                out payload);

                            // This can never fail, so I'm not checking the output
                            packet = new IEEE802_1x <Generic> {
                                Payload = payload
                            };
                        }

                        packet.Version    = version;
                        packet.Type       = type;
                        packet.BodyLength = bodyLength;

                        return(true);
                    }
                }
            }
            catch (Exception)
            {
                packet = null;
                return(false);
            }
        }