Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

updated SharpPcap to 4.1.0, updated PacketDotNet to 0.12.0

  • Loading branch information...
commit 751902faad1a006646470727b7f0692beb600579 1 parent b6cd28d
@ubivent-seuffert ubivent-seuffert authored
Showing with 13,663 additions and 4,171 deletions.
  1. +1 −1  PacketDotNet/AssemblyInfo.cs
  2. +1 −2  PacketDotNet/IGMPv2Packet.cs
  3. +6 −0 PacketDotNet/IPv4Packet.cs
  4. +116 −0 PacketDotNet/Ieee80211/AckFrame.cs
  5. +177 −0 PacketDotNet/Ieee80211/ActionFrame.cs
  6. +251 −0 PacketDotNet/Ieee80211/AssociationRequestFrame.cs
  7. +283 −0 PacketDotNet/Ieee80211/AssociationResponseFrame.cs
  8. +269 −0 PacketDotNet/Ieee80211/AuthenticationFrame.cs
  9. +166 −0 PacketDotNet/Ieee80211/AuthenticationStatusCode.cs
  10. +282 −0 PacketDotNet/Ieee80211/BeaconFrame.cs
  11. +166 −0 PacketDotNet/Ieee80211/BlockAcknowledgmentControlField.cs
  12. +303 −0 PacketDotNet/Ieee80211/BlockAcknowledgmentFrame.cs
  13. +231 −0 PacketDotNet/Ieee80211/BlockAcknowledgmentRequestFrame.cs
  14. +281 −0 PacketDotNet/Ieee80211/CapabilityInformationField.cs
  15. +129 −0 PacketDotNet/Ieee80211/ContentionFreeEndFrame.cs
  16. +116 −0 PacketDotNet/Ieee80211/CtsFrame.cs
  17. +110 −0 PacketDotNet/Ieee80211/DataDataFrame.cs
  18. +215 −0 PacketDotNet/Ieee80211/DataFrame.cs
  19. +169 −0 PacketDotNet/Ieee80211/DeauthenticationFrame.cs
  20. +168 −0 PacketDotNet/Ieee80211/DisassociationFrame.cs
  21. +60 −0 PacketDotNet/Ieee80211/DurationField.cs
  22. +579 −0 PacketDotNet/Ieee80211/FrameControlField.cs
  23. +372 −0 PacketDotNet/Ieee80211/InformationElement.cs
  24. +184 −0 PacketDotNet/Ieee80211/InformationElementList.cs
  25. +58 −0 PacketDotNet/Ieee80211/MacFields.cs
  26. +605 −0 PacketDotNet/Ieee80211/MacFrame.cs
  27. +102 −0 PacketDotNet/Ieee80211/ManagementFrame.cs
  28. +106 −0 PacketDotNet/Ieee80211/NullDataFrame.cs
  29. +97 −0 PacketDotNet/Ieee80211/PpiFieldType.cs
  30. +1,419 −0 PacketDotNet/Ieee80211/PpiFields.cs
  31. +89 −0 PacketDotNet/Ieee80211/PpiHeaderFields.cs
  32. +545 −0 PacketDotNet/Ieee80211/PpiPacket.cs
  33. +165 −0 PacketDotNet/Ieee80211/ProbeRequestFrame.cs
  34. +278 −0 PacketDotNet/Ieee80211/ProbeResponseFrame.cs
  35. +157 −0 PacketDotNet/Ieee80211/QosDataFrame.cs
  36. +152 −0 PacketDotNet/Ieee80211/QosNullDataFrame.cs
  37. +73 −0 PacketDotNet/Ieee80211/RadioFields.cs
  38. +425 −0 PacketDotNet/Ieee80211/RadioPacket.cs
  39. +53 −0 PacketDotNet/Ieee80211/RadioTapChannelFlags.cs
  40. +1,343 −0 PacketDotNet/Ieee80211/RadioTapFields.cs
  41. +63 −0 PacketDotNet/Ieee80211/RadioTapFlags.cs
  42. +178 −0 PacketDotNet/Ieee80211/RadioTapType.cs
  43. +169 −0 PacketDotNet/Ieee80211/ReasonCodes.cs
  44. +279 −0 PacketDotNet/Ieee80211/ReassociationRequestFrame.cs
  45. +94 −0 PacketDotNet/Ieee80211/RtsFrame.cs
  46. +104 −0 PacketDotNet/Ieee80211/SequenceControlField.cs
  47. +0 −309 PacketDotNet/Ieee80211FrameControlField.cs
  48. +0 −50 PacketDotNet/Ieee80211MacFields.cs
  49. +0 −362 PacketDotNet/Ieee80211MacFrame.cs
  50. +0 −70 PacketDotNet/Ieee80211RadioFields.cs
  51. +0 −233 PacketDotNet/Ieee80211RadioPacket.cs
  52. +0 −50 PacketDotNet/Ieee80211RadioTapChannelFlags.cs
  53. +0 −704 PacketDotNet/Ieee80211RadioTapFields.cs
  54. +0 −52 PacketDotNet/Ieee80211RadioTapFlags.cs
  55. +0 −176 PacketDotNet/Ieee80211RadioTapType.cs
  56. +6 −3 PacketDotNet/Packet.cs
  57. +48 −13 PacketDotNet/PacketDotNet.csproj
  58. +195 −0 PacketDotNet/Utils/Crc32.cs
  59. +17 −0 PacketDotNet/Utils/HexPrinter.cs
  60. +17 −0 PacketDotNet/Utils/RandomUtils.cs
  61. +29 −1 SharpPcap/AirPcap/AirPcapDevice.cs
  62. +5 −0 SharpPcap/AirPcap/AirPcapDeviceList.cs
  63. +1 −1  SharpPcap/AssemblyInfo.cs
  64. +7 −0 SharpPcap/LibPcap/CaptureFileWriterDevice.cs
  65. +1 −1  SharpPcap/LibPcap/PcapDevice.cs
  66. +1 −1  SharpPcap/WinPcap/WinPcapDevice.cs
  67. +2,147 −2,142 SharpPcap/docs/Api/SharpPcap.xml
View
2  PacketDotNet/AssemblyInfo.cs
@@ -17,7 +17,7 @@
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.
-[assembly: AssemblyVersion("0.11.0")]
+[assembly: AssemblyVersion("0.12.0")]
// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.
View
3  PacketDotNet/IGMPv2Packet.cs
@@ -149,7 +149,6 @@ public static IGMPv2Packet GetEncapsulated(Packet p)
var payload = InternetLinkLayerPacket.GetInnerPayload((InternetLinkLayerPacket)p);
if(payload is IpPacket)
{
- Console.WriteLine("Is an IP packet");
var innerPayload = payload.PayloadPacket;
if(innerPayload is IGMPv2Packet)
{
@@ -215,4 +214,4 @@ public override string ToString(StringOutputType outputFormat)
return buffer.ToString();
}
}
-}
+}
View
6 PacketDotNet/IPv4Packet.cs
@@ -524,6 +524,12 @@ public IPv4Packet(ByteArraySegment bas)
header = new ByteArraySegment(bas);
+ // TOS? See http://en.wikipedia.org/wiki/TCP_offload_engine
+ if (TotalLength == 0)
+ {
+ TotalLength = header.Length;
+ }
+
// Check that the TotalLength is valid, at least HeaderMinimumLength long
if(TotalLength < HeaderMinimumLength)
{
View
116 PacketDotNet/Ieee80211/AckFrame.cs
@@ -0,0 +1,116 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using PacketDotNet.Utils;
+using System.Net.NetworkInformation;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// Format of an ACK frame
+ /// </summary>
+ public class AckFrame : MacFrame
+ {
+ /// <summary>
+ /// Receiver address
+ /// </summary>
+ public PhysicalAddress ReceiverAddress {get; set;}
+
+ /// <summary>
+ /// Length of the frame
+ /// </summary>
+ override public int FrameSize
+ {
+ get
+ {
+ return (MacFields.FrameControlLength +
+ MacFields.DurationIDLength +
+ MacFields.AddressLength);
+ }
+ }
+
+ /// <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>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.AckFrame"/> class.
+ /// </summary>
+ /// <param name='ReceiverAddress'>
+ /// Receiver address.
+ /// </param>
+ public AckFrame (PhysicalAddress ReceiverAddress)
+ {
+ this.FrameControl = new FrameControlField ();
+ this.Duration = new DurationField ();
+ this.ReceiverAddress = ReceiverAddress;
+
+ this.FrameControl.SubType = FrameControlField.FrameSubTypes.ControlACK;
+ }
+
+ /// <summary>
+ /// Writes the current packet properties to the backing ByteArraySegment.
+ /// </summary>
+ public override void UpdateCalculatedValues ()
+ {
+ if ((header == null) || (header.Length > (header.BytesLength - header.Offset)) || (header.Length < FrameSize))
+ {
+ header = new ByteArraySegment (new Byte[FrameSize]);
+ }
+
+ this.FrameControlBytes = this.FrameControl.Field;
+ this.DurationBytes = this.Duration.Field;
+ SetAddress (0, ReceiverAddress);
+ }
+
+ /// <summary>
+ /// Returns a string with a description of the addresses used in the packet.
+ /// This is used as a compoent of the string returned by ToString().
+ /// </summary>
+ /// <returns>
+ /// The address string.
+ /// </returns>
+ protected override String GetAddressString()
+ {
+ return String.Format("RA {0}", ReceiverAddress);
+ }
+ }
+ }
+
+}
View
177 PacketDotNet/Ieee80211/ActionFrame.cs
@@ -0,0 +1,177 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using PacketDotNet.Utils;
+using System.Net.NetworkInformation;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ #region Action Category Enums
+
+
+ //The following enums define the category and type of action. At present these are
+ //not handled and parsed but they are left here for future reference as tracking them down
+ //was not that easy
+
+ //enum ActionCategory
+ //{
+ // SpectrumManagement = 0x0,
+ // Qos = 0x1,
+ // Dls = 0x2,
+ // BlockAck = 0x3,
+ // VendorSpecific = 0x127
+ //}
+
+ //enum SpectrumManagementAction
+ //{
+ // MeasurementRequest = 0x0,
+ // MeasurementReport = 0x1,
+ // TpcRequest = 0x2,
+ // TpcReport = 0x3,
+ // ChannelSwitchAnnouncement = 0x4
+ //}
+
+ //enum QosAction
+ //{
+ // TrafficSpecificationRequest = 0x0,
+ // TrafficSpecificationResponse = 0x1,
+ // TrafficSpecificationDelete = 0x2,
+ // Schedule = 0x3
+ //}
+
+ //enum DlsAction
+ //{
+ // DlsRequest = 0x0,
+ // DlsResponse = 0x1,
+ // DlsTeardown = 0x2
+ //}
+
+ //enum BlockAcknowledgmentActions
+ //{
+ // BlockAcknowledgmentRequest = 0x0,
+ // BlockAcknowledgmentResponse = 0x1,
+ // BlockAcknowledgmentDelete = 0x2
+ //}
+
+ #endregion
+
+ /// <summary>
+ /// Format of an 802.11 management action frame. These frames are used by the 802.11e (QoS) and 802.11n standards to request actions of stations.
+ /// </summary>
+ public class ActionFrame : ManagementFrame
+ {
+ /// <summary>
+ /// Gets the size of the frame in bytes
+ /// </summary>
+ /// <value>
+ /// The size of the frame.
+ /// </value>
+ public override int FrameSize
+ {
+ get
+ {
+ return (MacFields.FrameControlLength +
+ MacFields.DurationIDLength +
+ (MacFields.AddressLength * 3) +
+ MacFields.SequenceControlLength);
+ }
+ }
+
+ /// <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);
+ }
+ }
+
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.ActionFrame"/> class.
+ /// </summary>
+ /// <param name='SourceAddress'>
+ /// Source address.
+ /// </param>
+ /// <param name='DestinationAddress'>
+ /// Destination address.
+ /// </param>
+ /// <param name='BssId'>
+ /// Bss identifier.
+ /// </param>
+ public ActionFrame (PhysicalAddress SourceAddress,
+ PhysicalAddress DestinationAddress,
+ PhysicalAddress BssId)
+ {
+ this.FrameControl = new FrameControlField ();
+ this.Duration = new DurationField ();
+ this.DestinationAddress = DestinationAddress;
+ this.SourceAddress = SourceAddress;
+ this.BssId = BssId;
+ this.SequenceControl = new SequenceControlField ();
+
+ this.FrameControl.SubType = FrameControlField.FrameSubTypes.ManagementAction;
+ }
+
+ /// <summary>
+ /// Writes the current packet properties to the backing ByteArraySegment.
+ /// </summary>
+ public override void UpdateCalculatedValues ()
+ {
+ if ((header == null) || (header.Length > (header.BytesLength - header.Offset)) || (header.Length < FrameSize))
+ {
+ header = new ByteArraySegment (new Byte[FrameSize]);
+ }
+
+ this.FrameControlBytes = this.FrameControl.Field;
+ this.DurationBytes = this.Duration.Field;
+ SetAddress (0, DestinationAddress);
+ SetAddress (1, SourceAddress);
+ SetAddress (2, BssId);
+ this.SequenceControlBytes = this.SequenceControl.Field;
+
+ }
+
+ }
+
+ }
+}
View
251 PacketDotNet/Ieee80211/AssociationRequestFrame.cs
@@ -0,0 +1,251 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using PacketDotNet.Utils;
+using MiscUtil.Conversion;
+using System.Net.NetworkInformation;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// Format of an 802.11 management association frame.
+ /// </summary>
+ public class AssociationRequestFrame : ManagementFrame
+ {
+ private class AssociationRequestFields
+ {
+ public readonly static int CapabilityInformationLength = 2;
+ public readonly static int ListenIntervalLength = 2;
+
+ public readonly static int CapabilityInformationPosition;
+ public readonly static int ListenIntervalPosition;
+ public readonly static int InformationElement1Position;
+
+ static AssociationRequestFields()
+ {
+ CapabilityInformationPosition = MacFields.SequenceControlPosition + MacFields.SequenceControlLength;
+ ListenIntervalPosition = CapabilityInformationPosition + CapabilityInformationLength;
+ InformationElement1Position = ListenIntervalPosition + ListenIntervalLength;
+ }
+ }
+
+ /// <summary>
+ /// Frame control bytes are the first two bytes of the frame
+ /// </summary>
+ private UInt16 CapabilityInformationBytes
+ {
+ get
+ {
+ if(header.Length >=
+ (AssociationRequestFields.CapabilityInformationPosition + AssociationRequestFields.CapabilityInformationLength))
+ {
+ return EndianBitConverter.Little.ToUInt16(header.Bytes,
+ header.Offset + AssociationRequestFields.CapabilityInformationPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes(value,
+ header.Bytes,
+ header.Offset + AssociationRequestFields.CapabilityInformationPosition);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the capability information.
+ /// </summary>
+ /// <value>
+ /// The capability information.
+ /// </value>
+ public CapabilityInformationField CapabilityInformation
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets the listen interval.
+ /// </summary>
+ /// <value>
+ /// The listen interval.
+ /// </value>
+ public UInt16 ListenInterval {get; set;}
+
+ private UInt16 ListenIntervalBytes
+ {
+ get
+ {
+ if(header.Length >= (AssociationRequestFields.ListenIntervalPosition + AssociationRequestFields.ListenIntervalLength))
+ {
+ return EndianBitConverter.Little.ToUInt16(header.Bytes,
+ header.Offset + AssociationRequestFields.ListenIntervalPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes(value,
+ header.Bytes,
+ header.Offset + AssociationRequestFields.ListenIntervalPosition);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the information elements.
+ /// </summary>
+ /// <value>
+ /// The information elements.
+ /// </value>
+ public InformationElementList InformationElements { get; set; }
+
+ /// <summary>
+ /// Gets the size of the frame.
+ /// </summary>
+ /// <value>
+ /// The size of the frame.
+ /// </value>
+ public override int FrameSize
+ {
+ get
+ {
+ return (MacFields.FrameControlLength +
+ MacFields.DurationIDLength +
+ (MacFields.AddressLength * 3) +
+ MacFields.SequenceControlLength +
+ AssociationRequestFields.CapabilityInformationLength +
+ AssociationRequestFields.ListenIntervalLength +
+ InformationElements.Length);
+ }
+ }
+
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="bas">
+ /// A <see cref="ByteArraySegment"/>
+ /// </param>
+ public AssociationRequestFrame (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);
+ ListenInterval = ListenIntervalBytes;
+
+ if(bas.Length > AssociationRequestFields.InformationElement1Position)
+ {
+ //create a segment that just refers to the info element section
+ ByteArraySegment infoElementsSegment = new ByteArraySegment (bas.Bytes,
+ (bas.Offset + AssociationRequestFields.InformationElement1Position),
+ (bas.Length - AssociationRequestFields.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>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.AssociationRequestFrame"/> 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 AssociationRequestFrame (PhysicalAddress SourceAddress,
+ PhysicalAddress DestinationAddress,
+ PhysicalAddress BssId,
+ InformationElementList InformationElements)
+ {
+ this.FrameControl = new FrameControlField ();
+ this.Duration = new DurationField ();
+ this.DestinationAddress = DestinationAddress;
+ this.SourceAddress = SourceAddress;
+ this.BssId = BssId;
+ this.SequenceControl = new SequenceControlField ();
+ this.CapabilityInformation = new CapabilityInformationField ();
+ this.InformationElements = new InformationElementList (InformationElements);
+
+ this.FrameControl.SubType = FrameControlField.FrameSubTypes.ManagementAssociationRequest;
+ }
+
+ /// <summary>
+ /// Writes the current packet properties to the backing ByteArraySegment.
+ /// </summary>
+ public override void UpdateCalculatedValues ()
+ {
+ if ((header == null) || (header.Length > (header.BytesLength - header.Offset)) || (header.Length < FrameSize))
+ {
+ header = new ByteArraySegment (new Byte[FrameSize]);
+ }
+
+ this.FrameControlBytes = this.FrameControl.Field;
+ this.DurationBytes = this.Duration.Field;
+ SetAddress (0, DestinationAddress);
+ SetAddress (1, SourceAddress);
+ SetAddress (2, BssId);
+ this.SequenceControlBytes = this.SequenceControl.Field;
+ this.CapabilityInformationBytes = this.CapabilityInformation.Field;
+
+ //we now know the backing buffer is big enough to contain the info elements so we can safely copy them in
+ this.InformationElements.CopyTo (header, header.Offset + AssociationRequestFields.InformationElement1Position);
+
+ header.Length = FrameSize;
+ }
+
+ }
+ }
+}
View
283 PacketDotNet/Ieee80211/AssociationResponseFrame.cs
@@ -0,0 +1,283 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using PacketDotNet.Utils;
+using MiscUtil.Conversion;
+using System.Net.NetworkInformation;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// Format of an 802.11 management association response frame.
+ /// </summary>
+ public class AssociationResponseFrame : ManagementFrame
+ {
+ private class AssociationResponseFields
+ {
+ public readonly static int CapabilityInformationLength = 2;
+ public readonly static int StatusCodeLength = 2;
+ public readonly static int AssociationIdLength = 2;
+
+ public readonly static int CapabilityInformationPosition;
+ public readonly static int StatusCodePosition;
+ public readonly static int AssociationIdPosition;
+ public readonly static int InformationElement1Position;
+
+ static AssociationResponseFields()
+ {
+ CapabilityInformationPosition = MacFields.SequenceControlPosition + MacFields.SequenceControlLength;
+ StatusCodePosition = CapabilityInformationPosition + CapabilityInformationLength;
+ AssociationIdPosition = StatusCodePosition + StatusCodeLength;
+ InformationElement1Position = AssociationIdPosition + AssociationIdLength;
+ }
+ }
+
+ /// <summary>
+ /// The raw capability information bytes
+ /// </summary>
+ private UInt16 CapabilityInformationBytes
+ {
+ get
+ {
+ if(header.Length >=
+ (AssociationResponseFields.CapabilityInformationPosition + AssociationResponseFields.CapabilityInformationLength))
+ {
+ return EndianBitConverter.Little.ToUInt16(header.Bytes,
+ header.Offset + AssociationResponseFields.CapabilityInformationPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes(value,
+ header.Bytes,
+ header.Offset + AssociationResponseFields.CapabilityInformationPosition);
+ }
+ }
+
+ /// <summary>
+ /// The capability information field that describes the networks capabilities.
+ /// </summary>
+ public CapabilityInformationField CapabilityInformation
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Value indicating the success or failure of the association.
+ /// </summary>
+ public AuthenticationStatusCode StatusCode {get; set;}
+
+ private AuthenticationStatusCode StatusCodeBytes
+ {
+ get
+ {
+ if(header.Length >= (AssociationResponseFields.StatusCodePosition + AssociationResponseFields.StatusCodeLength))
+ {
+ return (AuthenticationStatusCode)EndianBitConverter.Little.ToUInt16 (header.Bytes,
+ header.Offset + AssociationResponseFields.StatusCodePosition);
+ }
+ else
+ {
+ //This seems the most sensible value to return when it is not possible
+ //to extract a meaningful value
+ return AuthenticationStatusCode.UnspecifiedFailure;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes ((UInt16)value,
+ header.Bytes,
+ header.Offset + AssociationResponseFields.StatusCodePosition);
+ }
+ }
+
+ /// <summary>
+ /// The id assigned to the station by the access point to assist in management and control functions.
+ ///
+ /// Although this is a 16bit field only 14 of the bits are used to represent the id. Therefore the available values
+ /// for this field are inthe range 1-2,007.
+ /// </summary>
+ public UInt16 AssociationId {get; set;}
+
+ private UInt16 AssociationIdBytes
+ {
+ get
+ {
+ if(header.Length >= AssociationResponseFields.AssociationIdPosition + AssociationResponseFields.AssociationIdLength)
+ {
+ UInt16 associationID = EndianBitConverter.Little.ToUInt16(header.Bytes, header.Offset + AssociationResponseFields.AssociationIdPosition);
+ return (UInt16)(associationID & 0xCF);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ UInt16 associationID = (UInt16)(value & 0xCF);
+ EndianBitConverter.Little.CopyBytes(associationID,
+ header.Bytes,
+ header.Offset + AssociationResponseFields.AssociationIdPosition);
+ }
+ }
+
+ /// <summary>
+ /// The information elements included in the frame
+ /// </summary>
+ public InformationElementList InformationElements { get; set; }
+
+ /// <summary>
+ /// Gets the size of the frame.
+ /// </summary>
+ /// <value>
+ /// The size of the frame.
+ /// </value>
+ public override int FrameSize
+ {
+ get
+ {
+ return (MacFields.FrameControlLength +
+ MacFields.DurationIDLength +
+ (MacFields.AddressLength * 3) +
+ MacFields.SequenceControlLength +
+ AssociationResponseFields.CapabilityInformationLength +
+ AssociationResponseFields.StatusCodeLength +
+ AssociationResponseFields.AssociationIdLength +
+ InformationElements.Length);
+ }
+ }
+
+
+ /// <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;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.AssociationResponseFrame"/> 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 AssociationResponseFrame (PhysicalAddress SourceAddress,
+ PhysicalAddress DestinationAddress,
+ PhysicalAddress BssId,
+ InformationElementList InformationElements)
+ {
+ this.FrameControl = new FrameControlField ();
+ this.Duration = new DurationField ();
+ this.DestinationAddress = DestinationAddress;
+ this.SourceAddress = SourceAddress;
+ this.BssId = BssId;
+ this.SequenceControl = new SequenceControlField ();
+ this.CapabilityInformation = new CapabilityInformationField ();
+
+ this.InformationElements = new InformationElementList (InformationElements);
+
+ this.FrameControl.SubType = FrameControlField.FrameSubTypes.ManagementAssociationResponse;
+ }
+
+ /// <summary>
+ /// Writes the current packet properties to the backing ByteArraySegment.
+ /// </summary>
+ public override void UpdateCalculatedValues ()
+ {
+ if ((header == null) || (header.Length > (header.BytesLength - header.Offset)) || (header.Length < FrameSize))
+ {
+ header = new ByteArraySegment (new Byte[FrameSize]);
+ }
+
+ this.FrameControlBytes = this.FrameControl.Field;
+ this.DurationBytes = this.Duration.Field;
+ SetAddress (0, DestinationAddress);
+ SetAddress (1, SourceAddress);
+ SetAddress (2, BssId);
+ this.SequenceControlBytes = this.SequenceControl.Field;
+ this.CapabilityInformationBytes = this.CapabilityInformation.Field;
+ this.StatusCodeBytes = this.StatusCode;
+ this.AssociationIdBytes = this.AssociationId;
+
+ //we now know the backing buffer is big enough to contain the info elements so we can safely copy them in
+ this.InformationElements.CopyTo (header, header.Offset + AssociationResponseFields.InformationElement1Position);
+
+ header.Length = FrameSize;
+ }
+
+ }
+ }
+}
View
269 PacketDotNet/Ieee80211/AuthenticationFrame.cs
@@ -0,0 +1,269 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using PacketDotNet.Utils;
+using MiscUtil.Conversion;
+using System.Net.NetworkInformation;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// Format of an 802.11 management authentication frame.
+ /// </summary>
+ public class AuthenticationFrame : ManagementFrame
+ {
+ private class AuthenticationFields
+ {
+ public readonly static int AuthAlgorithmNumLength = 2;
+ public readonly static int AuthAlgorithmTransactionSequenceNumLength = 2;
+ public readonly static int StatusCodeLength = 2;
+ public readonly static int AuthAlgorithmNumPosition;
+ public readonly static int AuthAlgorithmTransactionSequenceNumPosition;
+ public readonly static int StatusCodePosition;
+ public readonly static int InformationElement1Position;
+
+ static AuthenticationFields ()
+ {
+ AuthAlgorithmNumPosition = MacFields.SequenceControlPosition + MacFields.SequenceControlLength;
+ AuthAlgorithmTransactionSequenceNumPosition = AuthAlgorithmNumPosition + AuthAlgorithmNumLength;
+ StatusCodePosition = AuthAlgorithmTransactionSequenceNumPosition + AuthAlgorithmTransactionSequenceNumLength;
+ InformationElement1Position = StatusCodePosition + StatusCodeLength;
+ }
+ }
+
+ /// <summary>
+ /// Number used for selection of authentication algorithm
+ /// </summary>
+ public UInt16 AuthenticationAlgorithmNumber { get; set; }
+
+ private UInt16 AuthenticationAlgorithmNumberBytes
+ {
+ get
+ {
+ if(header.Length >=
+ (AuthenticationFields.AuthAlgorithmNumPosition + AuthenticationFields.AuthAlgorithmNumLength))
+ {
+ return EndianBitConverter.Little.ToUInt16 (header.Bytes,
+ header.Offset + AuthenticationFields.AuthAlgorithmNumPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes (value,
+ header.Bytes,
+ header.Offset + AuthenticationFields.AuthAlgorithmNumPosition);
+ }
+ }
+
+ /// <summary>
+ /// Sequence number to define the step of the authentication algorithm
+ /// </summary>
+ public UInt16 AuthenticationAlgorithmTransactionSequenceNumber { get; set; }
+
+ private UInt16 AuthenticationAlgorithmTransactionSequenceNumberBytes
+ {
+ get
+ {
+ if(header.Length >=
+ (AuthenticationFields.AuthAlgorithmTransactionSequenceNumPosition + AuthenticationFields.AuthAlgorithmTransactionSequenceNumLength))
+ {
+ return EndianBitConverter.Little.ToUInt16 (header.Bytes,
+ header.Offset + AuthenticationFields.AuthAlgorithmTransactionSequenceNumPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes (value,
+ header.Bytes,
+ header.Offset + AuthenticationFields.AuthAlgorithmTransactionSequenceNumPosition);
+ }
+ }
+
+ /// <summary>
+ /// Indicates the success or failure of the authentication operation
+ /// </summary>
+ public AuthenticationStatusCode StatusCode { get; set; }
+
+ private AuthenticationStatusCode StatusCodeBytes
+ {
+ get
+ {
+ if(header.Length >= (AuthenticationFields.StatusCodePosition + AuthenticationFields.StatusCodeLength))
+ {
+ return (AuthenticationStatusCode)EndianBitConverter.Little.ToUInt16 (header.Bytes,
+ header.Offset + AuthenticationFields.StatusCodePosition);
+ }
+ else
+ {
+ //This seems the most sensible value to return when it is not possible
+ //to extract a meaningful value
+ return AuthenticationStatusCode.UnspecifiedFailure;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes ((UInt16)value,
+ header.Bytes,
+ header.Offset + AuthenticationFields.StatusCodePosition);
+ }
+ }
+
+ /// <summary>
+ /// The information elements included in the frame
+ /// </summary>
+ public InformationElementList InformationElements { get; set; }
+
+ /// <summary>
+ /// Gets the size of the frame.
+ /// </summary>
+ /// <value>
+ /// The size of the frame.
+ /// </value>
+ public override int FrameSize
+ {
+ get
+ {
+ return (MacFields.FrameControlLength +
+ MacFields.DurationIDLength +
+ (MacFields.AddressLength * 3) +
+ MacFields.SequenceControlLength +
+ AuthenticationFields.AuthAlgorithmNumLength +
+ AuthenticationFields.AuthAlgorithmTransactionSequenceNumLength +
+ AuthenticationFields.StatusCodeLength +
+ InformationElements.Length);
+ }
+ }
+
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="bas">
+ /// A <see cref="ByteArraySegment"/>
+ /// </param>
+ public AuthenticationFrame (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);
+ AuthenticationAlgorithmNumber = AuthenticationAlgorithmNumberBytes;
+ AuthenticationAlgorithmTransactionSequenceNumber = AuthenticationAlgorithmTransactionSequenceNumberBytes;
+
+ if(bas.Length > AuthenticationFields.InformationElement1Position)
+ {
+ //create a segment that just refers to the info element section
+ ByteArraySegment infoElementsSegment = new ByteArraySegment (bas.Bytes,
+ (bas.Offset + AuthenticationFields.InformationElement1Position),
+ (bas.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>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.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)
+ {
+ this.FrameControl = new FrameControlField ();
+ this.Duration = new DurationField ();
+ this.DestinationAddress = DestinationAddress;
+ this.SourceAddress = SourceAddress;
+ this.BssId = BssId;
+ this.SequenceControl = new SequenceControlField ();
+ this.InformationElements = new InformationElementList (InformationElements);
+
+ this.FrameControl.SubType = FrameControlField.FrameSubTypes.ManagementAuthentication;
+ }
+
+ /// <summary>
+ /// Writes the current packet properties to the backing ByteArraySegment.
+ /// </summary>
+ public override void UpdateCalculatedValues ()
+ {
+ if ((header == null) || (header.Length > (header.BytesLength - header.Offset)) || (header.Length < FrameSize))
+ {
+ header = new ByteArraySegment (new Byte[FrameSize]);
+ }
+
+ this.FrameControlBytes = this.FrameControl.Field;
+ this.DurationBytes = this.Duration.Field;
+ SetAddress (0, DestinationAddress);
+ SetAddress (1, SourceAddress);
+ SetAddress (2, BssId);
+ this.SequenceControlBytes = this.SequenceControl.Field;
+ this.AuthenticationAlgorithmNumberBytes = this.AuthenticationAlgorithmNumber;
+ this.AuthenticationAlgorithmTransactionSequenceNumberBytes = this.AuthenticationAlgorithmTransactionSequenceNumber;
+ this.StatusCodeBytes = this.StatusCode;
+ //we now know the backing buffer is big enough to contain the info elements so we can safely copy them in
+ this.InformationElements.CopyTo (header, header.Offset + AuthenticationFields.InformationElement1Position);
+
+ header.Length = FrameSize;
+ }
+
+ }
+ }
+}
View
166 PacketDotNet/Ieee80211/AuthenticationStatusCode.cs
@@ -0,0 +1,166 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// The potential results of authentication or association operations.
+ /// </summary>
+ public enum AuthenticationStatusCode
+ {
+ /// <summary>
+ /// Constant success.
+ /// </summary>
+ Success = 0,
+
+ /// <summary>
+ /// Constant unspecified failure.
+ /// </summary>
+ UnspecifiedFailure = 1,
+
+ /// <summary>
+ /// Constant requested capability unsupportable.
+ /// </summary>
+ RequestedCapabilityUnsupportable = 10,
+
+ /// <summary>
+ /// Constant unidentifiable prior association.
+ /// </summary>
+ UnidentifiablePriorAssociation = 11,
+
+ /// <summary>
+ /// Constant non standard unspecified denial.
+ /// </summary>
+ NonStandardUnspecifiedDenial = 12,
+
+ /// <summary>
+ /// Constant authentication algorithm not supported.
+ /// </summary>
+ AuthenticationAlgorithmNotSupported = 13,
+
+ /// <summary>
+ /// Constant unexpected sequenec number.
+ /// </summary>
+ UnexpectedSequenecNumber = 14,
+
+ /// <summary>
+ /// Constant response to challenge failed.
+ /// </summary>
+ ResponseToChallengeFailed = 15,
+
+ /// <summary>
+ /// Constant next frame outside expected window.
+ /// </summary>
+ NextFrameOutsideExpectedWindow = 16,
+
+ /// <summary>
+ /// Constant access point resource constrained.
+ /// </summary>
+ AccessPointResourceConstrained = 17,
+
+ /// <summary>
+ /// Constant station doesnt support data rates.
+ /// </summary>
+ StationDoesntSupportDataRates = 18,
+
+ /// <summary>
+ /// Constant station doesnt support preamble.
+ /// </summary>
+ StationDoesntSupportPreamble = 19,
+
+ /// <summary>
+ /// Constant station doesnt support pbcc modulation.
+ /// </summary>
+ StationDoesntSupportPbccModulation = 20,
+
+ /// <summary>
+ /// Constant station doesnt support channel agility.
+ /// </summary>
+ StationDoesntSupportChannelAgility = 21,
+
+ /// <summary>
+ /// Constant spectrum management required.
+ /// </summary>
+ SpectrumManagementRequired = 22,
+
+ /// <summary>
+ /// Constant unacceptable power capability value.
+ /// </summary>
+ UnacceptablePowerCapabilityValue = 23,
+
+ /// <summary>
+ /// Constant unacceptable supported channels value.
+ /// </summary>
+ UnacceptableSupportedChannelsValue = 24,
+
+ /// <summary>
+ /// Constant station doesnt support short time slot.
+ /// </summary>
+ StationDoesntSupportShortTimeSlot = 25,
+
+ /// <summary>
+ /// Constant station doesnt support dsss ofdm.
+ /// </summary>
+ StationDoesntSupportDsssOfdm = 26,
+
+ /// <summary>
+ /// Constant invalid information element.
+ /// </summary>
+ InvalidInformationElement = 40,
+
+ /// <summary>
+ /// Constant invalid group cipher.
+ /// </summary>
+ InvalidGroupCipher = 41,
+
+ /// <summary>
+ /// Constant invalid pairwise cipher.
+ /// </summary>
+ InvalidPairwiseCipher = 42,
+
+ /// <summary>
+ /// Constant invalid authentication and key management protocol.
+ /// </summary>
+ InvalidAuthenticationAndKeyManagementProtocol = 43,
+
+ /// <summary>
+ /// Constant unsupported rsn information element version.
+ /// </summary>
+ UnsupportedRsnInformationElementVersion = 44,
+
+ /// <summary>
+ /// Constant unsupported rsn ie capabilities.
+ /// </summary>
+ UnsupportedRsnIeCapabilities = 45,
+
+ /// <summary>
+ /// Constant cipher suite policy rejection.
+ /// </summary>
+ CipherSuitePolicyRejection = 46
+ }
+ }
+}
View
282 PacketDotNet/Ieee80211/BeaconFrame.cs
@@ -0,0 +1,282 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using PacketDotNet.Utils;
+using MiscUtil.Conversion;
+using System.Net.NetworkInformation;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// Format of an 802.11 management beacon frame.
+ ///
+ /// Beacon frames are used to annouce the existance of a wireless network. If an
+ /// access point has been configured to not broadcast its SSID then it may not transmit
+ /// beacon frames.
+ /// </summary>
+ public class BeaconFrame : ManagementFrame
+ {
+
+ private class BeaconFields
+ {
+ public readonly static int TimestampLength = 8;
+ public readonly static int BeaconIntervalLength = 2;
+ public readonly static int CapabilityInformationLength = 2;
+
+ public readonly static int TimestampPosition;
+ public readonly static int BeaconIntervalPosition;
+ public readonly static int CapabilityInformationPosition;
+ public readonly static int InformationElement1Position;
+
+ static BeaconFields ()
+ {
+ TimestampPosition = MacFields.SequenceControlPosition + MacFields.SequenceControlLength;
+ BeaconIntervalPosition = TimestampPosition + TimestampLength;
+ CapabilityInformationPosition = BeaconIntervalPosition + BeaconIntervalLength;
+ InformationElement1Position = CapabilityInformationPosition + CapabilityInformationLength;
+ }
+ }
+
+
+ /// <summary>
+ /// The number of microseconds the networks master timekeeper has been active.
+ ///
+ /// Used for synchronisation between stations in an IBSS. When it reaches the maximum value the timestamp will wrap (not very likely).
+ /// </summary>
+ public UInt64 Timestamp {get; set;}
+
+ private UInt64 TimestampBytes
+ {
+ get
+ {
+ if(header.Length >= (BeaconFields.TimestampPosition + BeaconFields.TimestampLength))
+ {
+ return EndianBitConverter.Little.ToUInt64(header.Bytes, header.Offset + BeaconFields.TimestampPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes(value,
+ header.Bytes,
+ header.Offset + BeaconFields.TimestampPosition);
+ }
+ }
+
+ /// <summary>
+ /// The number of "time units" between beacon frames.
+ ///
+ /// A time unit is 1,024 microseconds. This interval is usually set to 100 which equates to approximately 100 milliseconds or 0.1 seconds.
+ /// </summary>
+ public UInt16 BeaconInterval {get; set;}
+
+ private UInt16 BeaconIntervalBytes
+ {
+ get
+ {
+ if(header.Length >= (BeaconFields.BeaconIntervalPosition + BeaconFields.BeaconIntervalLength))
+ {
+ return EndianBitConverter.Little.ToUInt16(header.Bytes, header.Offset + BeaconFields.BeaconIntervalPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes(value,
+ header.Bytes,
+ header.Offset + BeaconFields.BeaconIntervalPosition);
+ }
+ }
+
+ /// <summary>
+ /// Frame control bytes are the first two bytes of the frame
+ /// </summary>
+ private UInt16 CapabilityInformationBytes
+ {
+ get
+ {
+ if(header.Length >= (BeaconFields.CapabilityInformationPosition + BeaconFields.CapabilityInformationLength))
+ {
+ return EndianBitConverter.Little.ToUInt16(header.Bytes,
+ header.Offset + BeaconFields.CapabilityInformationPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes(value,
+ header.Bytes,
+ header.Offset + BeaconFields.CapabilityInformationPosition);
+ }
+ }
+
+ /// <summary>
+ /// Defines the capabilities of the network.
+ /// </summary>
+ public CapabilityInformationField CapabilityInformation
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets the size of the frame.
+ /// </summary>
+ /// <value>
+ /// The size of the frame.
+ /// </value>
+ public override int FrameSize
+ {
+ get
+ {
+ return (MacFields.FrameControlLength +
+ MacFields.DurationIDLength +
+ (MacFields.AddressLength * 3) +
+ MacFields.SequenceControlLength +
+ BeaconFields.TimestampLength +
+ BeaconFields.BeaconIntervalLength +
+ BeaconFields.CapabilityInformationLength +
+ InformationElements.Length);
+ }
+ }
+
+ /// <summary>
+ /// The information elements included in the frame
+ ///
+ /// Most (but not all) beacons frames will contain an Information element that contains the SSID.
+ /// </summary>
+ public InformationElementList InformationElements { get; private set; }
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="bas">
+ /// A <see cref="ByteArraySegment"/>
+ /// </param>
+ public BeaconFrame (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 > BeaconFields.InformationElement1Position)
+ {
+ //create a segment that just refers to the info element section
+ ByteArraySegment infoElementsSegment = new ByteArraySegment (bas.Bytes,
+ (bas.Offset + BeaconFields.InformationElement1Position),
+ (bas.Length - BeaconFields.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>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.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)
+ {
+ this.FrameControl = new FrameControlField ();
+ this.Duration = new DurationField ();
+ this.SequenceControl = new SequenceControlField ();
+ this.CapabilityInformation = new CapabilityInformationField ();
+ this.InformationElements = new InformationElementList (InformationElements);
+ this.FrameControl.SubType = FrameControlField.FrameSubTypes.ManagementBeacon;
+ this.SourceAddress = SourceAddress;
+ this.DestinationAddress = PhysicalAddress.Parse ("FF-FF-FF-FF-FF-FF");
+ this.BssId = BssId;
+ this.BeaconInterval = 100;
+ }
+
+ /// <summary>
+ /// Writes the current packet properties to the backing ByteArraySegment.
+ /// </summary>
+ public override void UpdateCalculatedValues ()
+ {
+
+ if ((header == null) || (header.Length > (header.BytesLength - header.Offset)) || (header.Length < FrameSize))
+ {
+ //the backing buffer isnt big enough to accommodate the info elements so we need to resize it
+ header = new ByteArraySegment (new Byte[FrameSize]);
+ }
+
+ this.FrameControlBytes = this.FrameControl.Field;
+ this.DurationBytes = this.Duration.Field;
+ SetAddress (0, DestinationAddress);
+ SetAddress (1, SourceAddress);
+ SetAddress (2, BssId);
+ this.SequenceControlBytes = this.SequenceControl.Field;
+ this.TimestampBytes = Timestamp;
+ this.BeaconIntervalBytes = BeaconInterval;
+ this.CapabilityInformationBytes = this.CapabilityInformation.Field;
+
+ //we now know the backing buffer is big enough to contain the info elements so we can safely copy them in
+ this.InformationElements.CopyTo (header, header.Offset + BeaconFields.InformationElement1Position);
+
+ header.Length = FrameSize;
+ }
+
+ }
+ }
+}
View
166 PacketDotNet/Ieee80211/BlockAcknowledgmentControlField.cs
@@ -0,0 +1,166 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// Block acknowledgment control field.
+ /// </summary>
+ public class BlockAcknowledgmentControlField
+ {
+ /// <summary>
+ /// The available block acknowledgement policies.
+ /// </summary>
+ public enum AcknowledgementPolicy
+ {
+ /// <summary>
+ /// The acknowledgement does not have to be sent immediately after the request
+ /// </summary>
+ Delayed = 0,
+ /// <summary>
+ /// The acknowledgement must be sent immediately after the request
+ /// </summary>
+ Immediate = 1,
+ }
+
+ /// <summary>
+ /// The block acknowledgement policy in use
+ /// </summary>
+ public AcknowledgementPolicy Policy
+ {
+ get
+ {
+ return (AcknowledgementPolicy)(Field & 0x1);
+ }
+
+ set
+ {
+ if (value == AcknowledgementPolicy.Immediate)
+ {
+ Field |= 0x1;
+ }
+ else
+ {
+ Field &= unchecked((UInt16)~(0x1));
+ }
+ }
+ }
+
+ /// <summary>
+ /// True if the acknowledgement can ack multi traffic ids
+ /// </summary>
+ public bool MultiTid
+ {
+ get
+ {
+ return (((Field >> 1) & 0x1) == 1) ? true : false;
+ }
+
+ set
+ {
+ if (value)
+ {
+ Field |= (1 << 0x1);
+ }
+ else
+ {
+ Field &= unchecked((UInt16)~(1 << 0x1));
+ }
+ }
+ }
+
+ /// <summary>
+ /// True if the frame is using a compressed acknowledgement bitmap.
+ ///
+ /// Newer standards used a compressed bitmap reducing its size
+ /// </summary>
+ public bool CompressedBitmap
+ {
+ get
+ {
+ return (((Field >> 2) & 0x1) == 1) ? true : false;
+ }
+
+ set
+ {
+ if (value)
+ {
+ Field |= (1 << 0x2);
+ }
+ else
+ {
+ Field &= unchecked((UInt16)~(1 << 0x2));
+ }
+ }
+ }
+
+ /// <summary>
+ /// The traffic id being ack'd
+ /// </summary>
+ public byte Tid
+ {
+ get
+ {
+ return (byte)(Field >> 12);
+ }
+
+ set
+ {
+ Field &= 0x0FFF;
+ Field |= (UInt16)(value << 12);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets the field. This provides direct access to the bytes that back all the other properties in the field.
+ /// </summary>
+ /// <value>
+ /// The field.
+ /// </value>
+ public UInt16 Field {get; set;}
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.BlockAcknowledgmentControlField"/> class.
+ /// </summary>
+ public BlockAcknowledgmentControlField ()
+ {
+
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.BlockAcknowledgmentControlField"/> class.
+ /// </summary>
+ /// <param name='field'>
+ /// Field.
+ /// </param>
+ public BlockAcknowledgmentControlField(UInt16 field)
+ {
+ Field = field;
+ }
+ }
+ }
+}
View
303 PacketDotNet/Ieee80211/BlockAcknowledgmentFrame.cs
@@ -0,0 +1,303 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Net.NetworkInformation;
+using PacketDotNet.Utils;
+using MiscUtil.Conversion;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// Format of the 802.11 block acknowledgment frame.
+ /// http://en.wikipedia.org/wiki/Block_acknowledgement
+ /// </summary>
+ public class BlockAcknowledgmentFrame : MacFrame
+ {
+ private class BlockAcknowledgmentField
+ {
+ public readonly static int BlockAckRequestControlLength = 2;
+ public readonly static int BlockAckStartingSequenceControlLength = 2;
+
+ public readonly static int BlockAckRequestControlPosition;
+ public readonly static int BlockAckStartingSequenceControlPosition;
+ public readonly static int BlockAckBitmapPosition;
+
+ static BlockAcknowledgmentField()
+ {
+ BlockAckRequestControlPosition = MacFields.DurationIDPosition + MacFields.DurationIDLength + (2 * MacFields.AddressLength);
+ BlockAckStartingSequenceControlPosition = BlockAckRequestControlPosition + BlockAckRequestControlLength;
+ BlockAckBitmapPosition = BlockAckStartingSequenceControlPosition + BlockAckStartingSequenceControlLength;
+ }
+ }
+
+ /// <summary>
+ /// Receiver address
+ /// </summary>
+ public PhysicalAddress ReceiverAddress {get; set;}
+
+ /// <summary>
+ /// Transmitter address
+ /// </summary>
+ public PhysicalAddress TransmitterAddress { get; set; }
+
+ /// <summary>
+ /// Gets or sets the block ack request control bytes.
+ /// </summary>
+ /// <value>
+ /// The block ack request control bytes.
+ /// </value>
+ private UInt16 BlockAckRequestControlBytes
+ {
+ get
+ {
+ if(header.Length >=
+ (BlockAcknowledgmentField.BlockAckRequestControlPosition + BlockAcknowledgmentField.BlockAckRequestControlLength))
+ {
+ return EndianBitConverter.Little.ToUInt16(header.Bytes,
+ header.Offset + BlockAcknowledgmentField.BlockAckRequestControlPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes(value,
+ header.Bytes,
+ header.Offset + BlockAcknowledgmentField.BlockAckRequestControlPosition);
+ }
+ }
+
+ /// <summary>
+ /// Block acknowledgment control field
+ /// </summary>
+ public BlockAcknowledgmentControlField BlockAcknowledgmentControl
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets the block ack starting sequence control.
+ /// </summary>
+ /// <value>
+ /// The block ack starting sequence control.
+ /// </value>
+ public UInt16 BlockAckStartingSequenceControl {get; set;}
+
+ private UInt16 BlockAckStartingSequenceControlBytes
+ {
+ get
+ {
+ if(header.Length >=
+ (BlockAcknowledgmentField.BlockAckStartingSequenceControlPosition + BlockAcknowledgmentField.BlockAckStartingSequenceControlLength))
+ {
+ return EndianBitConverter.Little.ToUInt16 (header.Bytes,
+ header.Offset + BlockAcknowledgmentField.BlockAckStartingSequenceControlPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes (value,
+ header.Bytes,
+ header.Offset + BlockAcknowledgmentField.BlockAckStartingSequenceControlPosition);
+ }
+ }
+
+ private byte[] blockAckBitmap;
+ /// <summary>
+ /// Gets or sets the block ack bitmap used to indicate the receive status of the MPDUs.
+ /// </summary>
+ /// <value>
+ /// The block ack bitmap.
+ /// </value>
+ /// <exception cref='ArgumentException'>
+ /// Is thrown when the bitmap is of an incorrect lenght. The bitmap must be either 8 or 64 btyes longs depending on whether or not
+ /// it is compressed.
+ /// </exception>
+ public Byte[] BlockAckBitmap
+ {
+ get
+ {
+ return blockAckBitmap;
+ }
+
+ set
+ {
+ if (value.Length == 8)
+ {
+ BlockAcknowledgmentControl.CompressedBitmap = true;
+ }
+ else if (value.Length == 64)
+ {
+ BlockAcknowledgmentControl.CompressedBitmap = false;
+ }
+ else
+ {
+ throw new ArgumentException ("Invalid BlockAckBitmap size. Must be either 8 or 64 bytes long.");
+ }
+
+ blockAckBitmap = value;
+ }
+ }
+
+ private Byte[] BlockAckBitmapBytes
+ {
+ get
+ {
+ Byte[] bitmap = new Byte[GetBitmapLength ()];
+ if(header.Length >= (BlockAcknowledgmentField.BlockAckBitmapPosition + GetBitmapLength()))
+ {
+ Array.Copy (header.Bytes,
+ (BlockAcknowledgmentField.BlockAckBitmapPosition),
+ bitmap,
+ 0,
+ GetBitmapLength ());
+ }
+ return bitmap;
+ }
+
+ set
+ {
+ Array.Copy (BlockAckBitmap,
+ 0,
+ header.Bytes,
+ BlockAcknowledgmentField.BlockAckBitmapPosition,
+ GetBitmapLength());
+ }
+ }
+
+
+ /// <summary>
+ /// Length of the frame
+ /// </summary>
+ override public int FrameSize
+ {
+ get
+ {
+ return (MacFields.FrameControlLength +
+ MacFields.DurationIDLength +
+ (MacFields.AddressLength * 2) +
+ BlockAcknowledgmentField.BlockAckRequestControlLength +
+ BlockAcknowledgmentField.BlockAckStartingSequenceControlLength +
+ GetBitmapLength());
+ }
+ }
+
+
+ private int GetBitmapLength()
+ {
+ return BlockAcknowledgmentControl.CompressedBitmap ? 8 : 64;
+ }
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="bas">
+ /// A <see cref="ByteArraySegment"/>
+ /// </param>
+ public BlockAcknowledgmentFrame (ByteArraySegment bas)
+ {
+ header = new ByteArraySegment (bas);
+
+ FrameControl = new FrameControlField (FrameControlBytes);
+ Duration = new DurationField (DurationBytes);
+ ReceiverAddress = GetAddress (0);
+ TransmitterAddress = GetAddress (1);
+ BlockAcknowledgmentControl = new BlockAcknowledgmentControlField (BlockAckRequestControlBytes);
+ BlockAckStartingSequenceControl = BlockAckStartingSequenceControlBytes;
+ BlockAckBitmap = BlockAckBitmapBytes;
+ header.Length = FrameSize;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.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)
+ {
+ this.FrameControl = new FrameControlField ();
+ this.Duration = new DurationField ();
+ this.ReceiverAddress = ReceiverAddress;
+ this.TransmitterAddress = TransmitterAddress;
+ this.BlockAcknowledgmentControl = new BlockAcknowledgmentControlField ();
+ this.BlockAckBitmap = BlockAckBitmap;
+
+ this.FrameControl.SubType = FrameControlField.FrameSubTypes.ControlBlockAcknowledgment;
+ }
+
+ /// <summary>
+ /// Writes the current packet properties to the backing ByteArraySegment.
+ /// </summary>
+ public override void UpdateCalculatedValues ()
+ {
+ if ((header == null) || (header.Length > (header.BytesLength - header.Offset)) || (header.Length < FrameSize))
+ {
+ header = new ByteArraySegment (new Byte[FrameSize]);
+ }
+
+ this.FrameControlBytes = this.FrameControl.Field;
+ this.DurationBytes = this.Duration.Field;
+ SetAddress (0, ReceiverAddress);
+ SetAddress (1, TransmitterAddress);
+
+ this.BlockAckRequestControlBytes = this.BlockAcknowledgmentControl.Field;
+ this.BlockAckStartingSequenceControlBytes = this.BlockAckStartingSequenceControl;
+ BlockAckBitmapBytes = BlockAckBitmap;
+
+ header.Length = FrameSize;
+ }
+
+ /// <summary>
+ /// Returns a string with a description of the addresses used in the packet.
+ /// This is used as a compoent of the string returned by ToString().
+ /// </summary>
+ /// <returns>
+ /// The address string.
+ /// </returns>
+ protected override String GetAddressString()
+ {
+ return String.Format("RA {0} TA {1}", ReceiverAddress, TransmitterAddress);
+ }
+ }
+ }
+}
View
231 PacketDotNet/Ieee80211/BlockAcknowledgmentRequestFrame.cs
@@ -0,0 +1,231 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Net.NetworkInformation;
+using PacketDotNet.Utils;
+using MiscUtil.Conversion;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// Block acknowledgment request frame.
+ /// </summary>
+ public class BlockAcknowledgmentRequestFrame : MacFrame
+ {
+ private class BlockAckRequestField
+ {
+ public readonly static int BlockAckRequestControlLength = 2;
+ public readonly static int BlockAckStartingSequenceControlLength = 2;
+
+ public readonly static int BlockAckRequestControlPosition;
+ public readonly static int BlockAckStartingSequenceControlPosition;
+
+ static BlockAckRequestField()
+ {
+ BlockAckRequestControlPosition = MacFields.DurationIDPosition + MacFields.DurationIDLength + (2 * MacFields.AddressLength);
+ BlockAckStartingSequenceControlPosition = BlockAckRequestControlPosition + BlockAckRequestControlLength;
+ }
+ }
+
+ /// <summary>
+ /// Receiver address
+ /// </summary>
+ public PhysicalAddress ReceiverAddress {get; set;}
+
+ /// <summary>
+ /// Transmitter address
+ /// </summary>
+ public PhysicalAddress TransmitterAddress {get; set;}
+
+ /// <summary>
+ /// Block acknowledgment control bytes are the first two bytes of the frame
+ /// </summary>
+ private UInt16 BlockAckRequestControlBytes
+ {
+ get
+ {
+ if(header.Length >=
+ (BlockAckRequestField.BlockAckRequestControlPosition +
+ BlockAckRequestField.BlockAckRequestControlLength))
+ {
+ return EndianBitConverter.Little.ToUInt16(header.Bytes,
+ header.Offset + BlockAckRequestField.BlockAckRequestControlPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes(value,
+ header.Bytes,
+ header.Offset + BlockAckRequestField.BlockAckRequestControlPosition);
+ }
+ }
+
+ /// <summary>
+ /// Block acknowledgment control field
+ /// </summary>
+ public BlockAcknowledgmentControlField BlockAcknowledgmentControl
+ {
+ get;
+ set;
+ }
+
+ /// <summary>
+ /// Gets or sets the sequence number of the first MSDU for which this
+ /// block acknowledgement request frame is sent
+ /// </summary>
+ /// <value>
+ /// The block ack starting sequence control field value
+ /// </value>
+ public UInt16 BlockAckStartingSequenceControl {get; set;}
+
+ /// <summary>
+ /// Gets or sets the block ack starting sequence control.
+ /// </summary>
+ /// <value>
+ /// The block ack starting sequence control.
+ /// </value>
+ private UInt16 BlockAckStartingSequenceControlBytes
+ {
+ get
+ {
+ if(header.Length >=
+ (BlockAckRequestField.BlockAckStartingSequenceControlPosition +
+ BlockAckRequestField.BlockAckStartingSequenceControlLength))
+ {
+ return EndianBitConverter.Little.ToUInt16(header.Bytes,
+ header.Offset + BlockAckRequestField.BlockAckStartingSequenceControlPosition);
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ set
+ {
+ EndianBitConverter.Little.CopyBytes(value,
+ header.Bytes,
+ header.Offset + BlockAckRequestField.BlockAckStartingSequenceControlPosition);
+ }
+ }
+
+
+ /// <summary>
+ /// Length of the frame
+ /// </summary>
+ override public int FrameSize
+ {
+ get
+ {
+ return (MacFields.FrameControlLength +
+ MacFields.DurationIDLength +
+ (MacFields.AddressLength * 2) +
+ BlockAckRequestField.BlockAckRequestControlLength +
+ BlockAckRequestField.BlockAckStartingSequenceControlLength);
+ }
+ }
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="bas">
+ /// A <see cref="ByteArraySegment"/>
+ /// </param>
+ public BlockAcknowledgmentRequestFrame (ByteArraySegment bas)
+ {
+ header = new ByteArraySegment (bas);
+
+ FrameControl = new FrameControlField (FrameControlBytes);
+ Duration = new DurationField (DurationBytes);
+ ReceiverAddress = GetAddress (0);
+ TransmitterAddress = GetAddress (1);
+ BlockAcknowledgmentControl = new BlockAcknowledgmentControlField (BlockAckRequestControlBytes);
+ BlockAckStartingSequenceControl = BlockAckStartingSequenceControlBytes;
+
+ header.Length = FrameSize;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="PacketDotNet.Ieee80211.BlockAcknowledgmentRequestFrame"/> class.
+ /// </summary>
+ /// <param name='TransmitterAddress'>
+ /// Transmitter address.
+ /// </param>
+ /// <param name='ReceiverAddress'>
+ /// Receiver address.
+ /// </param>
+ public BlockAcknowledgmentRequestFrame (PhysicalAddress TransmitterAddress,
+ PhysicalAddress ReceiverAddress)
+ {
+ this.FrameControl = new FrameControlField ();
+ this.Duration = new DurationField ();
+ this.ReceiverAddress = ReceiverAddress;
+ this.TransmitterAddress = TransmitterAddress;
+ this.BlockAcknowledgmentControl = new BlockAcknowledgmentControlField ();
+
+ this.FrameControl.SubType = FrameControlField.FrameSubTypes.ControlBlockAcknowledgmentRequest;
+ }
+
+ /// <summary>
+ /// Writes the current packet properties to the backing ByteArraySegment.
+ /// </summary>
+ public override void UpdateCalculatedValues ()
+ {
+ if ((header == null) || (header.Length > (header.BytesLength - header.Offset)) || (header.Length < FrameSize))
+ {
+ header = new ByteArraySegment (new Byte[FrameSize]);
+ }
+
+ this.FrameControlBytes = this.FrameControl.Field;
+ this.DurationBytes = this.Duration.Field;
+ SetAddress (0, ReceiverAddress);
+ SetAddress (1, TransmitterAddress);
+
+ this.BlockAckRequestControlBytes = this.BlockAcknowledgmentControl.Field;
+ this.BlockAckStartingSequenceControlBytes = this.BlockAckStartingSequenceControl;
+
+ header.Length = FrameSize;
+ }
+
+ /// <summary>
+ /// Returns a string with a description of the addresses used in the packet.
+ /// This is used as a compoent of the string returned by ToString().
+ /// </summary>
+ /// <returns>
+ /// The address string.
+ /// </returns>
+ protected override String GetAddressString()
+ {
+ return String.Format("RA {0} TA {1}", ReceiverAddress, TransmitterAddress);
+ }
+ }
+ }
+}
View
281 PacketDotNet/Ieee80211/CapabilityInformationField.cs
@@ -0,0 +1,281 @@
+/*
+This file is part of PacketDotNet
+
+PacketDotNet is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+PacketDotNet is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with PacketDotNet. If not, see <http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 2012 Alan Rushforth <alan.rushforth@gmail.com>
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PacketDotNet
+{
+ namespace Ieee80211
+ {
+ /// <summary>
+ /// Capability information field.
+ /// </summary>
+ public class CapabilityInformationField
+ {
+
+ /// <summary>
+ /// Is set to 1 when the beacon frame is representing an ESS (as opposed to an IBSS)
+ ///
+ /// This field and IsIbss should be mutually exclusive
+ /// </summary>
+ public bool IsEss
+ {
+ get
+ {
+ return GetBitFieldValue(0);
+ }
+
+ set
+ {
+ SetBitFieldValue(0, value);
+ }
+ }
+
+ /// <summary>
+ /// Is set to 1 when the beacon frame is representing an IBSS (as opposed to an ESS)
+ ///
+ /// This field and IsEss should be mutually exclusive
+ /// </summary>
+ public bool IsIbss
+ {
+ get
+ {
+ return GetBitFieldValue(1);
+ }
+
+ set
+ {
+ SetBitFieldValue(1, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this
+ /// <see cref="PacketDotNet.Ieee80211.CapabilityInformationField"/> cf pollable.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if cf pollable; otherwise, <c>false</c>.
+ /// </value>
+ public bool CfPollable
+ {
+ get
+ {
+ return GetBitFieldValue(2);
+ }
+
+ set
+ {
+ SetBitFieldValue(2, value);
+ }
+ }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether this
+ /// <see cref="PacketDotNet.Ieee80211.CapabilityInformationField"/> cf poll request.
+ /// </summary>
+ /// <value>
+ /// <c>true</c> if cf poll request; otherwise, <c>false</c>.
+ /// </value>