/// <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 SNAP 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 organizationCode = br.ReadBytes(3); var etherType = ByteOrder.NetworkToHostOrder(br.ReadUInt16()); packet = null; if (organizationCode[0] == 0 && organizationCode[1] == 0 && organizationCode[2] == 0) { switch (etherType) { case (ushort)EtherTypes.IPv4: { IPv4 payload; if (IPv4.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payload)) { packet = new SNAP <IPv4> { Payload = payload }; } } break; case (ushort)EtherTypes.ARP: { ARP payload; if (ARP.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payload)) { packet = new SNAP <ARP> { Payload = payload }; } } break; case (ushort)EtherTypes.EAPoLAN: { IEEE802_1x payload; if (IEEE802_1x.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payload)) { packet = new SNAP <IEEE802_1x> { Payload = payload }; } } break; } } if (packet == null) { Generic payload; Generic.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payload); // This can never fail, so I'm not checking the output packet = new SNAP <Generic> { Payload = payload }; } packet.OrganizationCode = organizationCode; packet.ProtocolID = etherType; return(true); } } } catch (Exception) { packet = null; return(false); } }
/// <summary> /// Attempts to parse raw data into a structured packet /// </summary> /// <param name="buffer">Raw data to parse</param> /// <param name="packet">Parsed packet</param> /// <param name="count">The length of the packet in bytes</param> /// <param name="index">The index into the buffer at which the packet begins</param> /// <returns>True if parsing was successful, false if it is not.</returns> internal static bool TryParse(byte[] buffer, int index, int count, out IEEE802_1x packet) { try { if (count < MinimumParseableBytes) { packet = null; return(false); } using (var ms = new MemoryStream(buffer, index, count, false)) { using (var br = new BinaryReader(ms)) { var version = br.ReadByte(); var type = br.ReadByte(); var bodyLength = ByteOrder.NetworkToHostOrder(br.ReadUInt16()); var payloadLength = Math.Min(bodyLength, (int)(count - br.BaseStream.Position)); packet = null; switch (type) { case (byte)Types.EAPOL_KEY: { EapolKey payload; if (EapolKey.TryParse( buffer, index + (int)br.BaseStream.Position, payloadLength, out payload)) { packet = new IEEE802_1x <EapolKey> { Payload = payload }; } } break; } if (packet == null) { Generic payload; Generic.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payload); // This can never fail, so I'm not checking the output packet = new IEEE802_1x <Generic> { Payload = payload }; } packet.Version = version; packet.Type = type; packet.BodyLength = bodyLength; return(true); } } } catch (Exception) { packet = null; return(false); } }
/// <summary> /// Attempts to parse raw data into a structured packet /// </summary> /// <param name="buffer">Raw data to parse</param> /// <param name="packet">Parsed packet</param> /// <param name="count">The length of the packet in bytes</param> /// <param name="index">The index into the buffer at which the packet begins</param> /// <returns>True if parsing was successful, false if it is not.</returns> internal static bool TryParse(byte[] buffer, int index, int count, out IEEE802_1x packet) { try { if (count < MinimumParseableBytes) { packet = null; return false; } using (var ms = new MemoryStream(buffer, index, count, false)) { using (var br = new BinaryReader(ms)) { var version = br.ReadByte(); var type = br.ReadByte(); var bodyLength = ByteOrder.NetworkToHostOrder(br.ReadUInt16()); var payloadLength = Math.Min(bodyLength, (int)(count - br.BaseStream.Position)); packet = null; switch (type) { case (byte)Types.EAPOL_KEY: { EapolKey payload; if (EapolKey.TryParse( buffer, index + (int)br.BaseStream.Position, payloadLength, out payload)) { packet = new IEEE802_1x<EapolKey> { Payload = payload }; } } break; } if (packet == null) { Generic payload; Generic.TryParse( buffer, index + (int)br.BaseStream.Position, (int)(count - br.BaseStream.Position), out payload); // This can never fail, so I'm not checking the output packet = new IEEE802_1x<Generic> { Payload = payload }; } packet.Version = version; packet.Type = type; packet.BodyLength = bodyLength; return true; } } } catch (Exception) { packet = null; return false; } }
/// <summary> /// Checks whether the specified pairwise transit key is valid for the EAPoL key /// </summary> /// <param name="eapolKey">The EAPoL key to check against</param> /// <param name="ptk">The pairwise transit key to check</param> /// <returns>True if the key is valid, false if it is not</returns> public static bool PtkIsValid(IEEE802_1x<EapolKey> eapolKey, byte[] ptk) { var tkip = (eapolKey.Payload.KeyInformation & 7) == 1; bool isValid; var MIC = eapolKey.Payload.MIC; eapolKey.Payload.MIC = new byte[MIC.Length]; try { HMAC hmac; var key = ptk.Take(16).ToArray(); if (tkip) { #if DOTNET5_4 throw new System.Exception("The current version of System.Security.Cryptography.Algorithms is missing HMACMD5."); #else hmac = new HMACMD5(key); #endif } else { hmac = new HMACSHA1(key); } var computedHash = hmac.ComputeHash(eapolKey.ToArray()); isValid = computedHash.Take(16).SequenceEqual(MIC.Take(16)); } finally { eapolKey.Payload.MIC = MIC; } return isValid; }