Beispiel #1
0
        /// <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 MSMon802_11 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 length            = br.ReadUInt16();
                        var opMode            = br.ReadUInt32();
                        var receiveFlags      = br.ReadUInt32();
                        var phyID             = br.ReadUInt32();
                        var chCenterFrequency = br.ReadUInt32();

                        var RSSI     = br.ReadInt32();
                        var dataRate = br.ReadByte();

                        var timestamp = br.ReadUInt64();

                        packet = null;

                        // TODO: Consider parsed length

                        IEEE802_11 payload80211;
                        if (IEEE802_11.TryParse(
                                buffer,
                                index + (int)br.BaseStream.Position,
                                (int)(count - br.BaseStream.Position),
                                out payload80211))
                        {
                            packet = new MSMon802_11 <IEEE802_11> {
                                Payload = payload80211
                            };
                        }

                        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 MSMon802_11 <Generic> {
                                Payload = payload
                            };
                        }

                        packet.Version         = version;
                        packet.LengthMS        = length;
                        packet.OpMode          = opMode;
                        packet.ReceiveFlags    = receiveFlags;
                        packet.PhyID           = phyID;
                        packet.CenterFrequency = chCenterFrequency;
                        packet.RSSI            = RSSI;
                        packet.DataRate        = dataRate;
                        packet.Timestamp       = timestamp;

                        return(true);
                    }
                }
            }
            catch (Exception)
            {
                packet = null;
                return(false);
            }
        }
Beispiel #2
0
        /// <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_11 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 frameControlVersionTypeAndSubtype = new BitVector32(br.ReadByte());
                        var frameControlFlags = new BitVector32(br.ReadByte());
                        var durationID        = br.ReadUInt16();

                        var toDS   = frameControlFlags[1];
                        var fromDS = frameControlFlags[2];

                        byte[] destination;
                        byte[] source;
                        byte[] bssid;
                        byte[] receiver    = null;
                        byte[] transmitter = null;
                        UInt16 sequenceControl;

                        if (!toDS)
                        {
                            destination = br.ReadBytes(6);

                            if (!fromDS)
                            {
                                source = br.ReadBytes(6);
                                bssid  = br.ReadBytes(6);
                            }
                            else
                            {
                                bssid  = br.ReadBytes(6);
                                source = br.ReadBytes(6);
                            }
                            sequenceControl = br.ReadUInt16(); //Was NTHO, wireshark disagrees
                        }
                        else
                        {
                            if (!fromDS)
                            {
                                bssid           = br.ReadBytes(6);
                                source          = br.ReadBytes(6);
                                destination     = br.ReadBytes(6);
                                sequenceControl = br.ReadUInt16(); //Was NTHO, wireshark disagrees
                            }
                            else
                            {
                                receiver        = br.ReadBytes(6);
                                transmitter     = br.ReadBytes(6);
                                bssid           = transmitter;     //Per airdecap-ng
                                destination     = br.ReadBytes(6);
                                sequenceControl = br.ReadUInt16(); //Was NTHO, wireshark disagrees
                                source          = br.ReadBytes(6);
                            }
                        }

                        var frameType =
                            frameControlVersionTypeAndSubtype[BitVector32.CreateSection(3, BitVector32.CreateSection(3))
                            ];
                        var subType =
                            frameControlVersionTypeAndSubtype[
                                BitVector32.CreateSection(15, BitVector32.CreateSection(15))];

                        byte[] qosControl = null;
                        if (frameType == (int)FrameTypes.Data && subType == (int)DataSubTypes.QoS)
                        {
                            qosControl = br.ReadBytes(2);
                        }

                        var    isProtected   = frameControlFlags[64];
                        byte[] ccmp_WEP_Data = null;

                        if (isProtected)
                        {
                            if (count - br.BaseStream.Position < 4)
                            {
                                packet = null;
                                return(false);
                            }
                            var firstFour = br.ReadBytes(4);
                            if (firstFour[3] == 0)
                            {
                                ccmp_WEP_Data = firstFour;
                            }
                            else
                            {
                                if (count - br.BaseStream.Position < 4)
                                {
                                    packet = null;
                                    return(false);
                                }
                                ccmp_WEP_Data = new byte[8];
                                firstFour.CopyTo(ccmp_WEP_Data, 0);
                                br.ReadBytes(4).CopyTo(ccmp_WEP_Data, 4);
                            }
                        }

                        var isWep = isProtected && ccmp_WEP_Data?.Length == 4;

                        if (count - br.BaseStream.Position - (isWep ? 4 : 0) < 0)
                        {
                            packet = null;
                            return(false);
                        }

                        var unsafePayloadLen = count - (int)br.BaseStream.Position - (isWep ? 4 : 0);
                        var safePayloadLen   = Math.Max(0, unsafePayloadLen);

                        packet = null;

                        if (frameType == (int)FrameTypes.Data && ((subType & 4) != 1) && !isProtected)
                        {
                            LLC payload;
                            if (LLC.TryParse(buffer, index + (int)br.BaseStream.Position, safePayloadLen, out payload))
                            {
                                packet = new IEEE802_11 <LLC> {
                                    Payload = payload
                                };
                            }
                        }
                        else if (frameType == (int)FrameTypes.Management && subType == (int)ManagementSubTypes.Beacon)
                        {
                            Beacon802_11 payload;
                            if (Beacon802_11.TryParse(
                                    buffer,
                                    index + (int)br.BaseStream.Position,
                                    safePayloadLen,
                                    out payload))
                            {
                                packet = new IEEE802_11 <Beacon802_11> {
                                    Payload = payload
                                };
                            }
                        }

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

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

                        br.BaseStream.Seek(packet.Payload.Length(), SeekOrigin.Current);

                        UInt32 wep_ICV = 0;
                        if (isWep)
                        {
                            wep_ICV = ByteOrder.NetworkToHostOrder(br.ReadUInt32());
                        }

                        packet.FrameControlVersionTypeAndSubtype = frameControlVersionTypeAndSubtype;
                        packet.FrameControlFlags = frameControlFlags;
                        packet.DurationID        = durationID;
                        packet.Destination       = destination;
                        packet.Source            = source;
                        packet.BSSID             = bssid;
                        packet.SequenceControl   = sequenceControl;
                        packet.Receiver          = receiver;
                        packet.Transmitter       = transmitter;
                        packet.QosControl        = qosControl;
                        packet.CCMP_WEP_Data     = ccmp_WEP_Data;
                        packet.WEP_ICV           = wep_ICV;

                        if (br.BaseStream.Position == count - 4)
                        {
                            packet.FrameCheckSequence = br.ReadUInt32();
                        }

                        return(true);
                    }
                }
            }
            catch (Exception)
            {
                packet = null;
                return(false);
            }
        }
        /// <summary>
        /// Decrypt a WEP-encrypted packet
        /// </summary>
        /// <param name="encryptedPacket">WEP encrypted packet</param>
        /// <param name="key">Decryption key</param>
        /// <param name="decrypted">Decrypted packet</param>
        /// <returns>True if successful, false if not</returns>
        public static bool TryDecryptWEP(IEEE802_11 encryptedPacket, byte[] key, out IPacket decrypted)
        {
            if (key.Length != 5 && key.Length != 13 && key.Length != 16 && key.Length != 29 && key.Length != 61)
            {
                //throw new ArgumentException("Invalid WEP key length. [5,13,16,29,61]");
                decrypted = null;
                return false;
            }

            if (encryptedPacket.FrameType != (int)FrameTypes.Data || !encryptedPacket.IsWep)
            {
                decrypted = null;
                return false;
            }

            var keyWithIV = new byte[key.Length + 3];
            Array.Copy(encryptedPacket.CCMP_WEP_Data, keyWithIV, 3);
            Array.Copy(key, 0, keyWithIV, 3, key.Length);

            var rc4 = new RC4(keyWithIV);
            var encryptedPayload =
                encryptedPacket.Payload.ToArray()
                    .Concat(BitConverter.GetBytes(ByteOrder.NetworkToHostOrder(encryptedPacket.WEP_ICV)))
                    .ToArray();
            var dec = new byte[encryptedPayload.Length];
            rc4.decrypt(encryptedPayload, encryptedPayload.Length, dec);

            var expectedCRC = BitConverter.ToUInt32(dec, dec.Length - 4);
            dec = dec.Take(dec.Length - 4).ToArray();

            if (Crc32Algorithm.Compute(dec) == expectedCRC)
            {
                var decryptedBytes =
                    encryptedPacket.ToArray().Take(24 + (encryptedPacket.QosControl?.Length ?? 0)).Concat(dec).ToArray();
                decryptedBytes[1] &= 191; //Everything except protected
                return IEEE802_11Factory.Instance.TryParse(decryptedBytes, out decrypted);
            }
            decrypted = null;
            return false;
        }
        /// <summary>
        /// Decrypt a packet encrypted with CCMP
        /// </summary>
        /// <param name="encryptedPacket">The encrypted packet</param>
        /// <param name="temporalKey">The temporal key</param>
        /// <param name="headerMode">Mode in which headers should be handled</param>
        /// <param name="decrypted">Decrypted packet</param>
        /// <returns>True if successful, false if not</returns>
        /// <remarks>Ported from airdecap-ng</remarks>
        public static bool TryDecryptCCMP(
            IEEE802_11 encryptedPacket,
            byte[] temporalKey,
            DecryptionHeaderMode headerMode,
            out IPacket decrypted)
        {
            if (temporalKey.Length != 16)
            {
                // throw new ArgumentException("temporalKey must be 16 bytes");
                decrypted = null;
                return false;
            }

            var decryptedBytes = encryptedPacket.ToArray();
            int z, data_len, blocks, last, offset;
            bool is_a4, is_qos;

            var B0 = new byte[16];
            var B = new byte[16];
            var MIC = new byte[16];
            var PacketNumber = new byte[6];
            var AdditionalAuthData = new byte[32];

            is_a4 = (decryptedBytes[1] & 3) == 3;
            is_qos = (decryptedBytes[0] & 0x8C) == 0x88;
            z = 24 + 6 * (is_a4 ? 1 : 0);
            z += 2 * (is_qos ? 1 : 0);

            PacketNumber[0] = decryptedBytes[z + 7];
            PacketNumber[1] = decryptedBytes[z + 6];
            PacketNumber[2] = decryptedBytes[z + 5];
            PacketNumber[3] = decryptedBytes[z + 4];
            PacketNumber[4] = decryptedBytes[z + 1];
            PacketNumber[5] = decryptedBytes[z + 0];

            data_len = decryptedBytes.Length - z - 8 - 8;

            B0[0] = 0x59;
            B0[1] = 0;
            Array.Copy(decryptedBytes, 10, B0, 2, 6);
            Array.Copy(PacketNumber, 0, B0, 8, 6);
            B0[14] = (byte)((data_len >> 8) & 0xFF);
            B0[15] = (byte)(data_len & 0xFF);

            AdditionalAuthData[2] = (byte)(decryptedBytes[0] & 0x8F);
            AdditionalAuthData[3] = (byte)(decryptedBytes[1] & 0xC7);
            Array.Copy(decryptedBytes, 4, AdditionalAuthData, 4, 3 * 6);
            AdditionalAuthData[22] = (byte)(decryptedBytes[22] & 0x0F);

            if (is_a4)
            {
                Array.Copy(decryptedBytes, 24, AdditionalAuthData, 24, 6);

                if (is_qos)
                {
                    AdditionalAuthData[30] = (byte)(decryptedBytes[z - 2] & 0x0F);
                    AdditionalAuthData[31] = 0;
                    B0[1] = AdditionalAuthData[30];
                    AdditionalAuthData[1] = 22 + 2 + 6;
                }
                else
                {
                    AdditionalAuthData[30] = 0;
                    AdditionalAuthData[31] = 0;

                    B0[1] = 0;
                    AdditionalAuthData[1] = 22 + 6;
                }
            }
            else
            {
                if (is_qos)
                {
                    AdditionalAuthData[24] = (byte)(decryptedBytes[z - 2] & 0x0F);
                    AdditionalAuthData[25] = 0;
                    B0[1] = AdditionalAuthData[24];
                    AdditionalAuthData[1] = 22 + 2;
                }
                else
                {
                    AdditionalAuthData[24] = 0;
                    AdditionalAuthData[25] = 0;

                    B0[1] = 0;
                    AdditionalAuthData[1] = 22;
                }
            }

            using (var aesFactory = Aes.Create())
            {
                aesFactory.Mode = CipherMode.ECB;
                aesFactory.Key = temporalKey;
                var aes = aesFactory.CreateEncryptor();

                aes.TransformBlock(B0, 0, B0.Length, MIC, 0);
                CFunctions.XOR(MIC, 0, AdditionalAuthData, 16);
                aes.TransformBlock(MIC, 0, MIC.Length, MIC, 0);
                CFunctions.XOR(MIC, 0, AdditionalAuthData.Skip(16).ToArray(), 16);
                aes.TransformBlock(MIC, 0, MIC.Length, MIC, 0);

                B0[0] &= 0x07;
                B0[14] = 0;
                B0[15] = 0;
                aes.TransformBlock(B0, 0, B0.Length, B, 0);
                CFunctions.XOR(decryptedBytes, decryptedBytes.Length - 8, B, 8);

                blocks = (data_len + 16 - 1) / 16;
                last = data_len % 16;
                offset = z + 8;

                for (var i = 1; i <= blocks; i++)
                {
                    var n = last > 0 && i == blocks ? last : 16;

                    B0[14] = (byte)((i >> 8) & 0xFF);
                    B0[15] = (byte)(i & 0xFF);

                    aes.TransformBlock(B0, 0, B0.Length, B, 0);
                    CFunctions.XOR(decryptedBytes, offset, B, n);
                    CFunctions.XOR(MIC, 0, decryptedBytes.Skip(offset).ToArray(), n);
                    aes.TransformBlock(MIC, 0, MIC.Length, MIC, 0);

                    offset += n;
                }
            }

            switch (headerMode)
            {
                case DecryptionHeaderMode.Removed:
                    {
                        decryptedBytes[1] &= 191; // Remove the protected bit
                        var decryptedBytesList = decryptedBytes.ToList();
                        decryptedBytesList.RemoveRange(34 - 8, 8);
                            // Remove CCMP Parameters (otherwise, without the protected bit it will break the parsing)
                        IEEE802_11 decryptedWithHeader;
                        if (IEEE802_11Factory.Instance.TryParse(decryptedBytesList.ToArray(), out decryptedWithHeader))
                        {
                            decrypted = decryptedWithHeader.Payload; // Remove the altered 802.11 header
                        }
                        else
                        {
                            decrypted = null;
                            return false;
                        }

                        break;
                    }
                case DecryptionHeaderMode.Modified:
                    {
                        decryptedBytes[1] &= 191; // Remove the protected bit
                        var decryptedBytesList = decryptedBytes.ToList();
                        decryptedBytesList.RemoveRange(34 - 8, 8);
                            // Remove CCMP Parameters (otherwise, without the protected bit it will break the parsing)
                        if (!IEEE802_11Factory.Instance.TryParse(decryptedBytesList.ToArray(), out decrypted))
                        {
                            return false;
                        }
                        break;
                    }
                case DecryptionHeaderMode.Untouched:
                    if (!IEEE802_11Factory.Instance.TryParse(decryptedBytes.ToArray(), out decrypted))
                    {
                        return false;
                    }
                    break;

                default:
                    decrypted = null;
                    return false;
            }

            return CFunctions.memcmp(decryptedBytes.Skip(offset).Take(8).ToArray(), MIC.Take(8).ToArray()) == 0;
        }
        /// <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_11 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 frameControlVersionTypeAndSubtype = new BitVector32(br.ReadByte());
                        var frameControlFlags = new BitVector32(br.ReadByte());
                        var durationID = br.ReadUInt16();

                        var toDS = frameControlFlags[1];
                        var fromDS = frameControlFlags[2];

                        byte[] destination;
                        byte[] source;
                        byte[] bssid;
                        byte[] receiver = null;
                        byte[] transmitter = null;
                        UInt16 sequenceControl;

                        if (!toDS)
                        {
                            destination = br.ReadBytes(6);

                            if (!fromDS)
                            {
                                source = br.ReadBytes(6);
                                bssid = br.ReadBytes(6);
                            }
                            else
                            {
                                bssid = br.ReadBytes(6);
                                source = br.ReadBytes(6);
                            }
                            sequenceControl = br.ReadUInt16(); //Was NTHO, wireshark disagrees
                        }
                        else
                        {
                            if (!fromDS)
                            {
                                bssid = br.ReadBytes(6);
                                source = br.ReadBytes(6);
                                destination = br.ReadBytes(6);
                                sequenceControl = br.ReadUInt16(); //Was NTHO, wireshark disagrees
                            }
                            else
                            {
                                receiver = br.ReadBytes(6);
                                transmitter = br.ReadBytes(6);
                                bssid = transmitter; //Per airdecap-ng
                                destination = br.ReadBytes(6);
                                sequenceControl = br.ReadUInt16(); //Was NTHO, wireshark disagrees
                                source = br.ReadBytes(6);
                            }
                        }

                        var frameType =
                            frameControlVersionTypeAndSubtype[BitVector32.CreateSection(3, BitVector32.CreateSection(3))
                                ];
                        var subType =
                            frameControlVersionTypeAndSubtype[
                                BitVector32.CreateSection(15, BitVector32.CreateSection(15))];

                        byte[] qosControl = null;
                        if (frameType == (int)FrameTypes.Data && subType == (int)DataSubTypes.QoS)
                        {
                            qosControl = br.ReadBytes(2);
                        }

                        var isProtected = frameControlFlags[64];
                        byte[] ccmp_WEP_Data = null;

                        if (isProtected)
                        {
                            if (count - br.BaseStream.Position < 4)
                            {
                                packet = null;
                                return false;
                            }
                            var firstFour = br.ReadBytes(4);
                            if (firstFour[3] == 0)
                            {
                                ccmp_WEP_Data = firstFour;
                            }
                            else
                            {
                                if (count - br.BaseStream.Position < 4)
                                {
                                    packet = null;
                                    return false;
                                }
                                ccmp_WEP_Data = new byte[8];
                                firstFour.CopyTo(ccmp_WEP_Data, 0);
                                br.ReadBytes(4).CopyTo(ccmp_WEP_Data, 4);
                            }
                        }

                        var isWep = isProtected && ccmp_WEP_Data?.Length == 4;

                        if (count - br.BaseStream.Position - (isWep ? 4 : 0) < 0)
                        {
                            packet = null;
                            return false;
                        }

                        var unsafePayloadLen = count - (int)br.BaseStream.Position - (isWep ? 4 : 0);
                        var safePayloadLen = Math.Max(0, unsafePayloadLen);

                        packet = null;

                        if (frameType == (int)FrameTypes.Data && ((subType & 4) != 1) && !isProtected)
                        {
                            LLC payload;
                            if (LLC.TryParse(buffer, index + (int)br.BaseStream.Position, safePayloadLen, out payload))
                            {
                                packet = new IEEE802_11<LLC> { Payload = payload };
                            }
                        }
                        else if (frameType == (int)FrameTypes.Management && subType == (int)ManagementSubTypes.Beacon)
                        {
                            Beacon802_11 payload;
                            if (Beacon802_11.TryParse(
                                buffer,
                                index + (int)br.BaseStream.Position,
                                safePayloadLen,
                                out payload))
                            {
                                packet = new IEEE802_11<Beacon802_11> { Payload = payload };
                            }
                        }

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

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

                        br.BaseStream.Seek(packet.Payload.Length(), SeekOrigin.Current);

                        UInt32 wep_ICV = 0;
                        if (isWep)
                        {
                            wep_ICV = ByteOrder.NetworkToHostOrder(br.ReadUInt32());
                        }

                        packet.FrameControlVersionTypeAndSubtype = frameControlVersionTypeAndSubtype;
                        packet.FrameControlFlags = frameControlFlags;
                        packet.DurationID = durationID;
                        packet.Destination = destination;
                        packet.Source = source;
                        packet.BSSID = bssid;
                        packet.SequenceControl = sequenceControl;
                        packet.Receiver = receiver;
                        packet.Transmitter = transmitter;
                        packet.QosControl = qosControl;
                        packet.CCMP_WEP_Data = ccmp_WEP_Data;
                        packet.WEP_ICV = wep_ICV;

                        if (br.BaseStream.Position == count - 4)
                        {
                            packet.FrameCheckSequence = br.ReadUInt32();
                        }

                        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 Radiotap packet)
        {
            try
            {
                using (var ms = new MemoryStream(buffer, index, count, false))
                {
                    using (var br = new BinaryReader(ms))
                    {
                        var version = br.ReadByte();
                        var pad     = br.ReadByte();
                        var length  = br.ReadUInt16();
                        var present = br.ReadUInt32();

                        if (count - br.BaseStream.Position < length - 8)
                        {
                            packet = null;
                            return(false);
                        }
                        var fieldData = br.ReadBytes(length - 8);

                        packet = null;

                        IEEE802_11 payload80211;
                        if (IEEE802_11.TryParse(
                                buffer,
                                index + (int)br.BaseStream.Position,
                                (int)(count - br.BaseStream.Position),
                                out payload80211))
                        {
                            packet = new Radiotap <IEEE802_11> {
                                Payload = payload80211
                            };
                        }

                        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 Radiotap <Generic> {
                                Payload = payload
                            };
                        }

                        packet.Version        = version;
                        packet.Pad            = pad;
                        packet.LengthRadiotap = length;
                        packet.Present        = present;
                        packet.FieldData      = fieldData;

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