Ejemplo n.º 1
0
            /// <summary>
            /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.QosDataFrame"/> class.
            /// </summary>
            /// <param name='bas'>
            /// A <see cref="ByteArraySegment"/>
            /// </param>
            public QosDataFrame(ByteArraySegment bas)
            {
                log.Debug("");

                header = new ByteArraySegment(bas);

                FrameControl    = new FrameControlField(FrameControlBytes);
                Duration        = new DurationField(DurationBytes);
                SequenceControl = new SequenceControlField(SequenceControlBytes);
                QosControl      = QosControlBytes;
                ReadAddresses();

                header.Length = FrameSize;
                var availablePayloadLength = GetAvailablePayloadLength();

                if (availablePayloadLength > 0)
                {
                    // if data is protected we have no visibility into it, otherwise it is a LLC packet and we
                    // should parse it
                    if (FrameControl.Protected)
                    {
                        payloadPacketOrData.TheByteArraySegment = header.EncapsulatedBytes(availablePayloadLength);
                    }
                    else
                    {
                        payloadPacketOrData.ThePacket = new LogicalLinkControl(header.EncapsulatedBytes());
                    }
                }
            }
Ejemplo n.º 2
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public AuthenticationFrame(ByteArraySegment byteArraySegment)
        {
            Header = new ByteArraySegment(byteArraySegment);

            FrameControl       = new FrameControlField(FrameControlBytes);
            Duration           = new DurationField(DurationBytes);
            DestinationAddress = GetAddress(0);
            SourceAddress      = GetAddress(1);
            BssId           = GetAddress(2);
            SequenceControl = new SequenceControlField(SequenceControlBytes);
            AuthenticationAlgorithmNumber = AuthenticationAlgorithmNumberBytes;
            AuthenticationAlgorithmTransactionSequenceNumber = AuthenticationAlgorithmTransactionSequenceNumberBytes;

            if (byteArraySegment.Length > AuthenticationFields.InformationElement1Position)
            {
                //create a segment that just refers to the info element section
                var infoElementsSegment = new ByteArraySegment(byteArraySegment.Bytes,
                                                               byteArraySegment.Offset + AuthenticationFields.InformationElement1Position,
                                                               byteArraySegment.Length - AuthenticationFields.InformationElement1Position);

                InformationElements = new InformationElementList(infoElementsSegment);
            }
            else
            {
                InformationElements = new InformationElementList();
            }

            //cant set length until after we have handled the information elements
            //as they vary in length
            Header.Length = FrameSize;
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public ReassociationRequestFrame(ByteArraySegment byteArraySegment)
        {
            Header = new ByteArraySegment(byteArraySegment);

            FrameControl       = new FrameControlField(FrameControlBytes);
            Duration           = new DurationField(DurationBytes);
            DestinationAddress = GetAddress(0);
            SourceAddress      = GetAddress(1);
            BssId           = GetAddress(2);
            SequenceControl = new SequenceControlField(SequenceControlBytes);

            CapabilityInformation     = new CapabilityInformationField(CapabilityInformationBytes);
            ListenInterval            = ListenIntervalBytes;
            CurrentAccessPointAddress = CurrentAccessPointAddressBytes;

            if (byteArraySegment.Length > ReassociationRequestFields.InformationElement1Position)
            {
                //create a segment that just refers to the info element section
                var infoElementsSegment = new ByteArraySegment(byteArraySegment.Bytes,
                                                               byteArraySegment.Offset + ReassociationRequestFields.InformationElement1Position,
                                                               byteArraySegment.Length - ReassociationRequestFields.InformationElement1Position);

                InformationElements = new InformationElementList(infoElementsSegment);
            }
            else
            {
                InformationElements = new InformationElementList();
            }

            //cant set length until after we have handled the information elements
            //as they vary in length
            Header.Length = FrameSize;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="bas">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public ProbeResponseFrame(ByteArraySegment bas)
        {
            Header = new ByteArraySegment(bas);

            FrameControl       = new FrameControlField(FrameControlBytes);
            Duration           = new DurationField(DurationBytes);
            DestinationAddress = GetAddress(0);
            SourceAddress      = GetAddress(1);
            BssId                 = GetAddress(2);
            SequenceControl       = new SequenceControlField(SequenceControlBytes);
            Timestamp             = TimestampBytes;
            BeaconInterval        = BeaconIntervalBytes;
            CapabilityInformation = new CapabilityInformationField(CapabilityInformationBytes);

            if (bas.Length > ProbeResponseFields.InformationElement1Position)
            {
                //create a segment that just refers to the info element section
                var infoElementsSegment = new ByteArraySegment(bas.Bytes,
                                                               bas.Offset + ProbeResponseFields.InformationElement1Position,
                                                               bas.Length - ProbeResponseFields.InformationElement1Position);

                InformationElements = new InformationElementList(infoElementsSegment);
            }
            else
            {
                InformationElements = new InformationElementList();
            }

            //cant set length until after we have handled the information elements
            //as they vary in length
            Header.Length = FrameSize;
        }
Ejemplo n.º 5
0
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="bas">
            /// A <see cref="ByteArraySegment"/>
            /// </param>
            public AssociationResponseFrame(ByteArraySegment bas)
            {
                header = new ByteArraySegment(bas);

                FrameControl       = new FrameControlField(FrameControlBytes);
                Duration           = new DurationField(DurationBytes);
                DestinationAddress = GetAddress(0);
                SourceAddress      = GetAddress(1);
                BssId           = GetAddress(2);
                SequenceControl = new SequenceControlField(SequenceControlBytes);

                CapabilityInformation = new CapabilityInformationField(CapabilityInformationBytes);
                StatusCode            = StatusCodeBytes;
                AssociationId         = AssociationIdBytes;

                if (bas.Length > AssociationResponseFields.InformationElement1Position)
                {
                    //create a segment that just refers to the info element section
                    ByteArraySegment infoElementsSegment = new ByteArraySegment(bas.Bytes,
                                                                                (bas.Offset + AssociationResponseFields.InformationElement1Position),
                                                                                (bas.Length - AssociationResponseFields.InformationElement1Position));

                    InformationElements = new InformationElementList(infoElementsSegment);
                }
                else
                {
                    InformationElements = new InformationElementList();
                }
                //cant set length until after we have handled the information elements
                //as they vary in length
                header.Length = FrameSize;
            }
Ejemplo n.º 6
0
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="bas">
            /// A <see cref="ByteArraySegment"/>
            /// </param>
            public ProbeRequestFrame(ByteArraySegment bas)
            {
                header = new ByteArraySegment(bas);

                FrameControl       = new FrameControlField(FrameControlBytes);
                Duration           = new DurationField(DurationBytes);
                DestinationAddress = GetAddress(0);
                SourceAddress      = GetAddress(1);
                BssId           = GetAddress(2);
                SequenceControl = new SequenceControlField(SequenceControlBytes);

                if (bas.Length > ProbeRequestFields.InformationElement1Position)
                {
                    //create a segment that just refers to the info element section
                    ByteArraySegment infoElementsSegment = new ByteArraySegment(bas.Bytes,
                                                                                (bas.Offset + ProbeRequestFields.InformationElement1Position),
                                                                                (bas.Length - ProbeRequestFields.InformationElement1Position));

                    InformationElements = new InformationElementList(infoElementsSegment);
                }
                else
                {
                    InformationElements = new InformationElementList();
                }
                //cant set length until after we have handled the information elements
                //as they vary in length
                header.Length = FrameSize;
            }
Ejemplo n.º 7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CtsFrame" /> class.
        /// </summary>
        /// <param name='receiverAddress'>
        /// Receiver address.
        /// </param>
        public CtsFrame(PhysicalAddress receiverAddress)
        {
            FrameControl    = new FrameControlField();
            Duration        = new DurationField();
            ReceiverAddress = receiverAddress;

            FrameControl.SubType = FrameControlField.FrameSubTypes.ControlCts;
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AcknowledgmentFrame" /> class.
        /// </summary>
        /// <param name='receiverAddress'>
        /// Receiver address.
        /// </param>
        public AcknowledgmentFrame(PhysicalAddress receiverAddress)
        {
            FrameControl    = new FrameControlField();
            Duration        = new DurationField();
            ReceiverAddress = receiverAddress;

            FrameControl.SubType = FrameControlField.FrameSubTypes.ControlAck;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="NullDataFrame" /> class.
        /// </summary>
        public NullDataFrame()
        {
            FrameControl    = new FrameControlField();
            Duration        = new DurationField();
            SequenceControl = new SequenceControlField();
            AssignDefaultAddresses();

            FrameControl.SubType = FrameControlField.FrameSubTypes.DataNullFunctionNoData;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public CtsFrame(ByteArraySegment byteArraySegment)
        {
            Header = new ByteArraySegment(byteArraySegment);

            FrameControl    = new FrameControlField(FrameControlBytes);
            Duration        = new DurationField(DurationBytes);
            ReceiverAddress = GetAddress(0);

            Header.Length = FrameSize;
        }
Ejemplo n.º 11
0
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="bas">
            /// A <see cref="ByteArraySegment"/>
            /// </param>
            public AckFrame(ByteArraySegment bas)
            {
                header = new ByteArraySegment(bas);

                FrameControl    = new FrameControlField(FrameControlBytes);
                Duration        = new DurationField(DurationBytes);
                ReceiverAddress = GetAddress(0);

                header.Length = FrameSize;
            }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="bas">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public ContentionFreeEndFrame(ByteArraySegment bas)
        {
            Header = new ByteArraySegment(bas);

            FrameControl    = new FrameControlField(FrameControlBytes);
            Duration        = new DurationField(DurationBytes);
            ReceiverAddress = GetAddress(0);
            BssId           = GetAddress(1);

            Header.Length = FrameSize;
        }
Ejemplo n.º 13
0
            /// <summary>
            /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.NullDataFrame"/> class.
            /// </summary>
            /// <param name='bas'>
            /// A <see cref="ByteArraySegment"/>
            /// </param>
            public NullDataFrame(ByteArraySegment bas)
            {
                header = new ByteArraySegment(bas);

                FrameControl    = new FrameControlField(FrameControlBytes);
                Duration        = new DurationField(DurationBytes);
                SequenceControl = new SequenceControlField(SequenceControlBytes);
                ReadAddresses();

                header.Length = FrameSize;
            }
Ejemplo n.º 14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ContentionFreeEndFrame" /> class.
        /// </summary>
        /// <param name='receiverAddress'>
        /// Receiver address.
        /// </param>
        /// <param name='bssId'>
        /// Bss identifier (MAC Address of the Access Point).
        /// </param>
        public ContentionFreeEndFrame
        (
            PhysicalAddress receiverAddress,
            PhysicalAddress bssId)
        {
            FrameControl    = new FrameControlField();
            Duration        = new DurationField();
            ReceiverAddress = receiverAddress;
            BssId           = bssId;

            FrameControl.SubType = FrameControlField.FrameSubTypes.ControlCFEnd;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="QosNullDataFrame" /> class.
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public QosNullDataFrame(ByteArraySegment byteArraySegment)
        {
            Header = new ByteArraySegment(byteArraySegment);

            FrameControl    = new FrameControlField(FrameControlBytes);
            Duration        = new DurationField(DurationBytes);
            SequenceControl = new SequenceControlField(SequenceControlBytes);
            QosControl      = QosControlBytes;
            ReadAddresses();

            Header.Length = FrameSize;
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BlockAcknowledgmentRequestFrame" /> class.
        /// </summary>
        /// <param name='transmitterAddress'>
        /// Transmitter address.
        /// </param>
        /// <param name='receiverAddress'>
        /// Receiver address.
        /// </param>
        public BlockAcknowledgmentRequestFrame
        (
            PhysicalAddress transmitterAddress,
            PhysicalAddress receiverAddress)
        {
            FrameControl               = new FrameControlField();
            Duration                   = new DurationField();
            ReceiverAddress            = receiverAddress;
            TransmitterAddress         = transmitterAddress;
            BlockAcknowledgmentControl = new BlockAcknowledgmentControlField();

            FrameControl.SubType = FrameControlField.FrameSubTypes.ControlBlockAcknowledgmentRequest;
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public BlockAcknowledgmentRequestFrame(ByteArraySegment byteArraySegment)
        {
            Header = new ByteArraySegment(byteArraySegment);

            FrameControl                    = new FrameControlField(FrameControlBytes);
            Duration                        = new DurationField(DurationBytes);
            ReceiverAddress                 = GetAddress(0);
            TransmitterAddress              = GetAddress(1);
            BlockAcknowledgmentControl      = new BlockAcknowledgmentControlField(BlockAckRequestControlBytes);
            BlockAckStartingSequenceControl = BlockAckStartingSequenceControlBytes;

            Header.Length = FrameSize;
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public DeauthenticationFrame(ByteArraySegment byteArraySegment)
        {
            Header = new ByteArraySegment(byteArraySegment);

            FrameControl       = new FrameControlField(FrameControlBytes);
            Duration           = new DurationField(DurationBytes);
            DestinationAddress = GetAddress(0);
            SourceAddress      = GetAddress(1);
            BssId           = GetAddress(2);
            SequenceControl = new SequenceControlField(SequenceControlBytes);
            Reason          = ReasonBytes;

            Header.Length = FrameSize;
        }
Ejemplo n.º 19
0
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="bas">
            /// A <see cref="ByteArraySegment"/>
            /// </param>
            public DisassociationFrame(ByteArraySegment bas)
            {
                header = new ByteArraySegment(bas);

                FrameControl       = new FrameControlField(FrameControlBytes);
                Duration           = new DurationField(DurationBytes);
                DestinationAddress = GetAddress(0);
                SourceAddress      = GetAddress(1);
                BssId           = GetAddress(2);
                SequenceControl = new SequenceControlField(SequenceControlBytes);
                Reason          = ReasonBytes;

                header.Length = FrameSize;
            }
Ejemplo n.º 20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BlockAcknowledgmentFrame" /> class.
        /// </summary>
        /// <param name='transmitterAddress'>
        /// Transmitter address.
        /// </param>
        /// <param name='receiverAddress'>
        /// Receiver address.
        /// </param>
        /// <param name='blockAckBitmap'>
        /// The Block ack bitmap signalling the receive status of the MSDUs.
        /// </param>
        public BlockAcknowledgmentFrame
        (
            PhysicalAddress transmitterAddress,
            PhysicalAddress receiverAddress,
            byte[] blockAckBitmap)
        {
            FrameControl               = new FrameControlField();
            Duration                   = new DurationField();
            ReceiverAddress            = receiverAddress;
            TransmitterAddress         = transmitterAddress;
            BlockAcknowledgmentControl = new BlockAcknowledgmentControlField();
            BlockAckBitmap             = blockAckBitmap;

            FrameControl.SubType = FrameControlField.FrameSubTypes.ControlBlockAcknowledgment;
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DisassociationFrame" /> class.
        /// </summary>
        /// <param name='sourceAddress'>
        /// Source address.
        /// </param>
        /// <param name='destinationAddress'>
        /// Destination address.
        /// </param>
        /// <param name='bssId'>
        /// Bss identifier (MAC Address of the Access Point).
        /// </param>
        public DisassociationFrame
        (
            PhysicalAddress sourceAddress,
            PhysicalAddress destinationAddress,
            PhysicalAddress bssId)
        {
            FrameControl       = new FrameControlField();
            Duration           = new DurationField();
            DestinationAddress = destinationAddress;
            SourceAddress      = sourceAddress;
            BssId           = bssId;
            SequenceControl = new SequenceControlField();

            FrameControl.SubType = FrameControlField.FrameSubTypes.ManagementDisassociation;
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Initializes a new instance of the <see cref="AuthenticationFrame" /> class.
        /// </summary>
        /// <param name='sourceAddress'>
        /// Source address.
        /// </param>
        /// <param name='destinationAddress'>
        /// Destination address.
        /// </param>
        /// <param name='bssId'>
        /// Bss identifier (MAC Address of Access Point).
        /// </param>
        /// <param name='informationElements'>
        /// Information elements.
        /// </param>
        public AuthenticationFrame
        (
            PhysicalAddress sourceAddress,
            PhysicalAddress destinationAddress,
            PhysicalAddress bssId,
            InformationElementList informationElements)
        {
            FrameControl       = new FrameControlField();
            Duration           = new DurationField();
            DestinationAddress = destinationAddress;
            SourceAddress      = sourceAddress;
            BssId               = bssId;
            SequenceControl     = new SequenceControlField();
            InformationElements = new InformationElementList(informationElements);

            FrameControl.SubType = FrameControlField.FrameSubTypes.ManagementAuthentication;
        }
Ejemplo n.º 23
0
            /// <summary>
            /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.DataDataFrame"/> class.
            /// </summary>
            /// <param name='bas'>
            /// Bas.
            /// </param>
            public DataDataFrame(ByteArraySegment bas)
            {
                header = new ByteArraySegment(bas);

                FrameControl    = new FrameControlField(FrameControlBytes);
                Duration        = new DurationField(DurationBytes);
                SequenceControl = new SequenceControlField(SequenceControlBytes);
                ReadAddresses();  //must do this after reading FrameControl

                header.Length = FrameSize;
                var availablePayloadLength = GetAvailablePayloadLength();

                if (availablePayloadLength > 0)
                {
                    payloadPacketOrData.TheByteArraySegment = header.EncapsulatedBytes(availablePayloadLength);
                }
            }
Ejemplo n.º 24
0
        /// <summary>
        /// Initializes a new instance of the <see cref="DataDataFrame" /> class.
        /// </summary>
        /// <param name="byteArraySegment">
        /// byteArraySegment.
        /// </param>
        public DataDataFrame(ByteArraySegment byteArraySegment)
        {
            Header = new ByteArraySegment(byteArraySegment);

            FrameControl    = new FrameControlField(FrameControlBytes);
            Duration        = new DurationField(DurationBytes);
            SequenceControl = new SequenceControlField(SequenceControlBytes);
            ReadAddresses(); //must do this after reading FrameControl

            Header.Length = FrameSize;
            var availablePayloadLength = GetAvailablePayloadLength();

            if (availablePayloadLength > 0)
            {
                PayloadPacketOrData.Value.ByteArraySegment = Header.NextSegment(availablePayloadLength);
            }
        }
Ejemplo n.º 25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BeaconFrame" /> class.
 /// </summary>
 /// <param name='sourceAddress'>
 /// Source address.
 /// </param>
 /// <param name='bssId'>
 /// Bss identifier (MAC Address of the Access Point).
 /// </param>
 /// <param name='informationElements'>
 /// Information elements.
 /// </param>
 public BeaconFrame
 (
     PhysicalAddress sourceAddress,
     PhysicalAddress bssId,
     InformationElementList informationElements)
 {
     FrameControl          = new FrameControlField();
     Duration              = new DurationField();
     SequenceControl       = new SequenceControlField();
     CapabilityInformation = new CapabilityInformationField();
     InformationElements   = new InformationElementList(informationElements);
     FrameControl.SubType  = FrameControlField.FrameSubTypes.ManagementBeacon;
     SourceAddress         = sourceAddress;
     DestinationAddress    = PhysicalAddress.Parse("FF-FF-FF-FF-FF-FF");
     BssId          = bssId;
     BeaconInterval = 100;
 }
Ejemplo n.º 26
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ProbeResponseFrame" /> class.
        /// </summary>
        /// <param name='sourceAddress'>
        /// Source address.
        /// </param>
        /// <param name='destinationAddress'>
        /// Destination address.
        /// </param>
        /// <param name='bssId'>
        /// Bss identifier (Mac address of the access point).
        /// </param>
        /// <param name='informationElements'>
        /// Information elements.
        /// </param>
        public ProbeResponseFrame
        (
            PhysicalAddress sourceAddress,
            PhysicalAddress destinationAddress,
            PhysicalAddress bssId,
            InformationElementList informationElements)
        {
            FrameControl       = new FrameControlField();
            Duration           = new DurationField();
            DestinationAddress = destinationAddress;
            SourceAddress      = sourceAddress;
            BssId                 = bssId;
            SequenceControl       = new SequenceControlField();
            CapabilityInformation = new CapabilityInformationField();
            InformationElements   = new InformationElementList(informationElements);

            FrameControl.SubType = FrameControlField.FrameSubTypes.ManagementProbeResponse;
        }
Ejemplo n.º 27
0
            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="bas">
            /// A <see cref="ByteArraySegment"/>
            /// </param>
            public ActionFrame(ByteArraySegment bas)
            {
                header = new ByteArraySegment(bas);

                FrameControl       = new FrameControlField(FrameControlBytes);
                Duration           = new DurationField(DurationBytes);
                DestinationAddress = GetAddress(0);
                SourceAddress      = GetAddress(1);
                BssId           = GetAddress(2);
                SequenceControl = new SequenceControlField(SequenceControlBytes);

                header.Length = FrameSize;
                var availablePayloadLength = GetAvailablePayloadLength();

                if (availablePayloadLength > 0)
                {
                    payloadPacketOrData.TheByteArraySegment = header.EncapsulatedBytes(availablePayloadLength);
                }
            }
Ejemplo n.º 28
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="byteArraySegment">
        /// A <see cref="ByteArraySegment" />
        /// </param>
        public ActionFrame(ByteArraySegment byteArraySegment)
        {
            Header = new ByteArraySegment(byteArraySegment);

            FrameControl       = new FrameControlField(FrameControlBytes);
            Duration           = new DurationField(DurationBytes);
            DestinationAddress = GetAddress(0);
            SourceAddress      = GetAddress(1);
            BssId           = GetAddress(2);
            SequenceControl = new SequenceControlField(SequenceControlBytes);

            Header.Length = FrameSize;
            var availablePayloadLength = GetAvailablePayloadLength();

            if (availablePayloadLength > 0)
            {
                PayloadPacketOrData.Value.ByteArraySegment = Header.NextSegment(availablePayloadLength);
            }
        }
Ejemplo n.º 29
0
            /// <summary>
            /// Parses the <see cref="PacketDotNet.Utils.ByteArraySegment"/> into a MacFrame.
            /// </summary>
            /// <returns>
            /// The parsed MacFrame or null if it could not be parsed.
            /// </returns>
            /// <param name='bas'>
            /// The bytes of the packet. bas.Offset should point to the first byte in the mac frame.
            /// </param>
            /// <remarks>If the provided bytes contain the FCS then call <see cref="MacFrame.ParsePacketWithFcs"/> instead. The presence of the
            /// FCS is usually determined by configuration of the device used to capture the packets.</remarks>
            public static MacFrame ParsePacket(ByteArraySegment bas)
            {
                if (bas.Length < MacFields.FrameControlLength)
                {
                    //there isn't enough data to even try and work out what type of packet it is
                    return(null);
                }
                //this is a bit ugly as we will end up parsing the framecontrol field twice, once here and once
                //inside the packet constructor. Could create the framecontrol and pass it to the packet but I think that is equally ugly
                FrameControlField frameControl = new FrameControlField(
                    EndianBitConverter.Big.ToUInt16(bas.Bytes, bas.Offset));

                MacFrame macFrame = null;

                log.DebugFormat("SubType {0}", frameControl.SubType);

                switch (frameControl.SubType)
                {
                case FrameControlField.FrameSubTypes.ManagementAssociationRequest:
                {
                    macFrame = new AssociationRequestFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementAssociationResponse:
                {
                    macFrame = new AssociationResponseFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementReassociationRequest:
                {
                    macFrame = new ReassociationRequestFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementReassociationResponse:
                {
                    macFrame = new AssociationResponseFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementProbeRequest:
                {
                    macFrame = new ProbeRequestFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementProbeResponse:
                {
                    macFrame = new ProbeResponseFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementReserved0:
                    break; //TODO

                case FrameControlField.FrameSubTypes.ManagementReserved1:
                    break; //TODO

                case FrameControlField.FrameSubTypes.ManagementBeacon:
                {
                    macFrame = new BeaconFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementATIM:
                    break; //TODO

                case FrameControlField.FrameSubTypes.ManagementDisassociation:
                {
                    macFrame = new DisassociationFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementAuthentication:
                {
                    macFrame = new AuthenticationFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementDeauthentication:
                {
                    macFrame = new DeauthenticationFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementAction:
                {
                    macFrame = new ActionFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ManagementReserved3:
                    break; //TODO

                case FrameControlField.FrameSubTypes.ControlBlockAcknowledgmentRequest:
                {
                    macFrame = new BlockAcknowledgmentRequestFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ControlBlockAcknowledgment:
                {
                    macFrame = new BlockAcknowledgmentFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ControlPSPoll:
                    break; //TODO

                case FrameControlField.FrameSubTypes.ControlRTS:
                {
                    macFrame = new RtsFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ControlCTS:
                {
                    macFrame = new CtsFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ControlACK:
                {
                    macFrame = new AckFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ControlCFEnd:
                {
                    macFrame = new ContentionFreeEndFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.ControlCFEndCFACK:
                    break; //TODO

                case FrameControlField.FrameSubTypes.Data:
                case FrameControlField.FrameSubTypes.DataCFACK:
                case FrameControlField.FrameSubTypes.DataCFPoll:
                case FrameControlField.FrameSubTypes.DataCFAckCFPoll:
                {
                    macFrame = new DataDataFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.DataNullFunctionNoData:
                case FrameControlField.FrameSubTypes.DataCFAckNoData:
                case FrameControlField.FrameSubTypes.DataCFPollNoData:
                case FrameControlField.FrameSubTypes.DataCFAckCFPollNoData:
                {
                    macFrame = new NullDataFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.QosData:
                case FrameControlField.FrameSubTypes.QosDataAndCFAck:
                case FrameControlField.FrameSubTypes.QosDataAndCFPoll:
                case FrameControlField.FrameSubTypes.QosDataAndCFAckAndCFPoll:
                {
                    macFrame = new QosDataFrame(bas);
                    break;
                }

                case FrameControlField.FrameSubTypes.QosNullData:
                case FrameControlField.FrameSubTypes.QosCFAck:
                case FrameControlField.FrameSubTypes.QosCFPoll:
                case FrameControlField.FrameSubTypes.QosCFAckAndCFPoll:
                {
                    macFrame = new QosNullDataFrame(bas);
                    break;
                }

                default:
                    //this is an unsupported (and unknown) packet type
                    break;
                }

                return(macFrame);
            }