/// <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 DNSQuery 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 messageBytes = br.ReadBytes(count); var header = Header.FromArray(messageBytes); if (header.Response || header.QuestionCount == 0 || header.AdditionalRecordCount + header.AnswerRecordCount + header.AuthorityRecordCount > 0 || header.ResponseCode != ResponseCode.NoError) { packet = null; return(false); } var questions = Question.GetAllFromArray(messageBytes, header.Size, header.QuestionCount); packet = new DNSQuery(header, questions); 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 UDP 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 sourcePort = ByteOrder.NetworkToHostOrder(br.ReadUInt16()); var destPort = ByteOrder.NetworkToHostOrder(br.ReadUInt16()); var totalLength = ByteOrder.NetworkToHostOrder(br.ReadUInt16()); var checksum = ByteOrder.NetworkToHostOrder(br.ReadUInt16()); packet = null; if (destPort == 53) { if (DNSQuery.TryParse(buffer, index + (int)br.BaseStream.Position, count - 8, out DNSQuery payload)) { packet = new UDP <DNSQuery> { Payload = payload }; } } else if (sourcePort == 53) { if (DNSReply.TryParse(buffer, index + (int)br.BaseStream.Position, count - 8, out DNSReply payload)) { packet = new UDP <DNSReply> { Payload = payload }; } } if (packet == null) { // This can never fail, so I'm not checking the output Generic.TryParse(buffer, index + (int)br.BaseStream.Position, count - 8, out Generic payload); packet = new UDP <Generic>() { Payload = payload }; } packet.SourcePort = sourcePort; packet.DestPort = destPort; packet.TotalLength = totalLength; packet.Checksum = checksum; return(true); } } } catch (Exception) { packet = null; return(false); } }