/// <summary> /// Attempts to parse raw data into a structured packet /// </summary> /// <param name="buffer">Raw data to parse</param> /// <param name="packet">Parsed packet</param> /// <param name="count">The length of the packet in bytes</param> /// <param name="index">The index into the buffer at which the packet begins</param> /// <returns>True if parsing was successful, false if it is not.</returns> internal static bool TryParse(byte[] buffer, int index, int count, out LLC packet) { try { if (count < MinimumParseableBytes) { packet = null; return(false); } using (var ms = new MemoryStream(buffer, index, count, false)) { using (var br = new BinaryReader(ms)) { var dsap = br.ReadByte(); var ssap = br.ReadByte(); byte commandControl = 0; UInt16 responseControl = 0; if (dsap % 2 == 0) { commandControl = br.ReadByte(); } else if (count < 4) { packet = null; return(false); } else { responseControl = br.ReadUInt16(); } SNAP payloadSNAP; if (SNAP.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payloadSNAP)) { packet = new LLC <SNAP> { Payload = payloadSNAP }; } else { Generic payloadGeneric; Generic.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payloadGeneric); // This can never fail, so I'm not checking the output packet = new LLC <Generic> { Payload = payloadGeneric }; } packet.DSAP = dsap; packet.SSAP = ssap; packet.CommandControl = commandControl; packet.ResponseControl = responseControl; return(true); } } } catch (Exception) { packet = null; return(false); } }
/// <summary> /// Attempts to parse raw data into a structured packet /// </summary> /// <param name="buffer">Raw data to parse</param> /// <param name="packet">Parsed packet</param> /// <param name="count">The length of the packet in bytes</param> /// <param name="index">The index into the buffer at which the packet begins</param> /// <returns>True if parsing was successful, false if it is not.</returns> internal static bool TryParse(byte[] buffer, int index, int count, out LLC packet) { try { if (count < MinimumParseableBytes) { packet = null; return false; } using (var ms = new MemoryStream(buffer, index, count, false)) { using (var br = new BinaryReader(ms)) { var dsap = br.ReadByte(); var ssap = br.ReadByte(); byte commandControl = 0; UInt16 responseControl = 0; if (dsap % 2 == 0) { commandControl = br.ReadByte(); } else if (count < 4) { packet = null; return false; } else { responseControl = br.ReadUInt16(); } SNAP payloadSNAP; if (SNAP.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payloadSNAP)) { packet = new LLC<SNAP> { Payload = payloadSNAP }; } else { Generic payloadGeneric; Generic.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payloadGeneric); // This can never fail, so I'm not checking the output packet = new LLC<Generic> { Payload = payloadGeneric }; } packet.DSAP = dsap; packet.SSAP = ssap; packet.CommandControl = commandControl; packet.ResponseControl = responseControl; return true; } } } catch (Exception) { packet = null; return false; } }
/// <summary> /// Attempts to parse raw data into a structured packet /// </summary> /// <param name="buffer">Raw data to parse</param> /// <param name="packet">Parsed packet</param> /// <param name="count">The length of the packet in bytes</param> /// <param name="index">The index into the buffer at which the packet begins</param> /// <returns>True if parsing was successful, false if it is not.</returns> internal static bool TryParse(byte[] buffer, int index, int count, out IEEE802_11 packet) { try { if (count < MinimumParseableBytes) { packet = null; return(false); } using (var ms = new MemoryStream(buffer, index, count, false)) { using (var br = new BinaryReader(ms)) { var frameControlVersionTypeAndSubtype = new BitVector32(br.ReadByte()); var frameControlFlags = new BitVector32(br.ReadByte()); var durationID = br.ReadUInt16(); var toDS = frameControlFlags[1]; var fromDS = frameControlFlags[2]; byte[] destination; byte[] source; byte[] bssid; byte[] receiver = null; byte[] transmitter = null; UInt16 sequenceControl; if (!toDS) { destination = br.ReadBytes(6); if (!fromDS) { source = br.ReadBytes(6); bssid = br.ReadBytes(6); } else { bssid = br.ReadBytes(6); source = br.ReadBytes(6); } sequenceControl = br.ReadUInt16(); //Was NTHO, wireshark disagrees } else { if (!fromDS) { bssid = br.ReadBytes(6); source = br.ReadBytes(6); destination = br.ReadBytes(6); sequenceControl = br.ReadUInt16(); //Was NTHO, wireshark disagrees } else { receiver = br.ReadBytes(6); transmitter = br.ReadBytes(6); bssid = transmitter; //Per airdecap-ng destination = br.ReadBytes(6); sequenceControl = br.ReadUInt16(); //Was NTHO, wireshark disagrees source = br.ReadBytes(6); } } var frameType = frameControlVersionTypeAndSubtype[BitVector32.CreateSection(3, BitVector32.CreateSection(3)) ]; var subType = frameControlVersionTypeAndSubtype[ BitVector32.CreateSection(15, BitVector32.CreateSection(15))]; byte[] qosControl = null; if (frameType == (int)FrameTypes.Data && subType == (int)DataSubTypes.QoS) { qosControl = br.ReadBytes(2); } var isProtected = frameControlFlags[64]; byte[] ccmp_WEP_Data = null; if (isProtected) { if (count - br.BaseStream.Position < 4) { packet = null; return(false); } var firstFour = br.ReadBytes(4); if (firstFour[3] == 0) { ccmp_WEP_Data = firstFour; } else { if (count - br.BaseStream.Position < 4) { packet = null; return(false); } ccmp_WEP_Data = new byte[8]; firstFour.CopyTo(ccmp_WEP_Data, 0); br.ReadBytes(4).CopyTo(ccmp_WEP_Data, 4); } } var isWep = isProtected && ccmp_WEP_Data?.Length == 4; if (count - br.BaseStream.Position - (isWep ? 4 : 0) < 0) { packet = null; return(false); } var unsafePayloadLen = count - (int)br.BaseStream.Position - (isWep ? 4 : 0); var safePayloadLen = Math.Max(0, unsafePayloadLen); packet = null; if (frameType == (int)FrameTypes.Data && ((subType & 4) != 1) && !isProtected) { LLC payload; if (LLC.TryParse(buffer, index + (int)br.BaseStream.Position, safePayloadLen, out payload)) { packet = new IEEE802_11 <LLC> { Payload = payload }; } } else if (frameType == (int)FrameTypes.Management && subType == (int)ManagementSubTypes.Beacon) { Beacon802_11 payload; if (Beacon802_11.TryParse( buffer, index + (int)br.BaseStream.Position, safePayloadLen, out payload)) { packet = new IEEE802_11 <Beacon802_11> { Payload = payload }; } } if (packet == null) { Generic payload; Generic.TryParse(buffer, index + (int)br.BaseStream.Position, safePayloadLen, out payload); // This can never fail, so I'm not checking the output packet = new IEEE802_11 <Generic> { Payload = payload }; } br.BaseStream.Seek(packet.Payload.Length(), SeekOrigin.Current); UInt32 wep_ICV = 0; if (isWep) { wep_ICV = ByteOrder.NetworkToHostOrder(br.ReadUInt32()); } packet.FrameControlVersionTypeAndSubtype = frameControlVersionTypeAndSubtype; packet.FrameControlFlags = frameControlFlags; packet.DurationID = durationID; packet.Destination = destination; packet.Source = source; packet.BSSID = bssid; packet.SequenceControl = sequenceControl; packet.Receiver = receiver; packet.Transmitter = transmitter; packet.QosControl = qosControl; packet.CCMP_WEP_Data = ccmp_WEP_Data; packet.WEP_ICV = wep_ICV; if (br.BaseStream.Position == count - 4) { packet.FrameCheckSequence = br.ReadUInt32(); } return(true); } } } catch (Exception) { packet = null; return(false); } }