/* * Header Structure, the bit labeled 0 is the most significant bit. * * 0 1 2 3 4 5 6 7 8 9 A B C D E F +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ID | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ |QR| Opcode |AA|TC|RD|RA| Z | RCODE | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | QDCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ANCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | NSCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ | ARCOUNT | +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ */ //////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Encode header. </summary> /// /// <param name="message"> The message. </param> /// /// <returns> A byte[]. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// public static byte[] EncodeHeader(DnsMessage message) { MemoryStream stream = new MemoryStream(12); BinaryWriter writer = new BinaryWriter(stream); WriteUInt16BE(writer, message.ID); int fields = (int)message.ResponseCode; if (message.IsRecursionAvailable) { fields |= 0x80; } if (message.IsRecursionDesired) { fields |= 0x100; } if (message.IsTruncated) { fields |= 0x200; } if (message.IsRecursionAvailable) { fields |= 0x400; } fields |= (int)message.QueryKind << 11; //Opcode if (message.Type == MessageType.Response) { fields |= 0x8000; } WriteUInt16BE(writer, (UInt16)fields); WriteUInt16BE(writer, (UInt16)message.Querys.Count); WriteUInt16BE(writer, (UInt16)message.Answers.Count); WriteUInt16BE(writer, (UInt16)message.AuthorityRecords.Count); WriteUInt16BE(writer, (UInt16)message.AdditionalRecords.Count); return(stream.ToArray()); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Decode DNS message. </summary> /// /// <param name="msgData"> Information describing the message. </param> /// /// <returns> A DnsMessage. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// public static DnsMessage DecodeDnsMessage(byte[] msgData) { DnsMessage message = new DnsMessage(); message.ID = (UInt16)(msgData[0] << 8 | msgData[1]); message.Type = (MessageType)(msgData[2] >> 7); message.QueryKind = (QueryKind)((msgData[2] >> 3) & 15); message.ResponseCode = (ResponseCode)(msgData[3] & 15); MemoryStream stream = new MemoryStream(msgData); stream.Position = 4; BinaryReader reader = new BinaryReader(stream); int queryCount = ReadUInt16BE(reader); int answerCount = ReadUInt16BE(reader); int nsCount = ReadUInt16BE(reader); int arCount = ReadUInt16BE(reader); for (int i = 0; i < queryCount; i++) { message.Querys.Add(ReadDnsQuery(reader)); } for (int i = 0; i < answerCount; i++) { message.Answers.Add(ReadResourceRecord(reader)); } for (int i = 0; i < nsCount; i++) { message.AuthorityRecords.Add(ReadResourceRecord(reader)); } for (int i = 0; i < arCount; i++) { message.AdditionalRecords.Add(ReadResourceRecord(reader)); } return(message); }