public static IMessage Deserialize(ref byte[] Raw) { var Stream = new DnStream(ref Raw); var Message = new Message { ID = Stream.GetUShort(), MessageType = Stream.GetBit().AsEnum <MessageType>(), OperationCode = Stream.GetBits(4).AsEnum <OperationCode>(), AuthoritativeAnswer = Stream.GetBit().AsEnum <AuthoritativeAnswer>(), Truncated = Stream.GetBit().AsBool(), RecursionDesired = Stream.GetBit().AsBool(), RecursionAvailable = Stream.GetBit().AsBool(), Zero = Stream.GetBit(), AuthenticatedData = Stream.GetBit().AsBool(), CheckingDisabled = Stream.GetBit().AsBool(), ResponseCode = Stream.GetBits(4).AsEnum <ResponseCode>(), QuestionsCount = Stream.GetUShort(), AnswersCount = Stream.GetUShort(), AuthorityCount = Stream.GetUShort(), AdditionalCount = Stream.GetUShort() }; Message.Questions = GetQuestions(ref Stream, Message.QuestionsCount); Message.Answers = GetAnswers(ref Stream, Message.AnswersCount); return(Message); }
private static void Set(ref DnStream Stream, ref Dictionary <string, ushort> Pointers, IEnumerable <IAnswer> Answers) { foreach (var Answer in Answers) { Set(ref Stream, ref Pointers, Answer); } }
private static void Set(ref DnStream Stream, ref Dictionary <string, ushort> Pointers, IEnumerable <IQuestion> Questions) { foreach (var Question in Questions) { Set(ref Stream, ref Pointers, Question); } }
private static void Set(ref DnStream Stream, ref Dictionary <string, ushort> Pointers, IQuestion Question) { Set(ref Stream, ref Pointers, Question.Domain); Stream.SetUShort((byte)Question.Type); Stream.SetUShort((byte)Question.Class); }
private static IRecord GetRecord(ref DnStream Stream, RecordType RecordType) { return(RecordType switch { RecordType.A => GetA(ref Stream), RecordType.CNAME => GetCNAME(ref Stream), RecordType.AAAA => GetAAAA(ref Stream), _ => throw new ArgumentOutOfRangeException(nameof(RecordType), RecordType, null) });
private static IDomain GetDomain(ref DnStream Stream) { var Domain = new Domain() { Labels = GetLabels(ref Stream), }; return(Domain); }
private static IQuestion GetQuestion(ref DnStream Stream) { var Question = new Question() { Domain = GetDomain(ref Stream), Type = Stream.GetUShort().AsEnum <RecordType>(), Class = Stream.GetUShort().AsEnum <RecordClass>() }; return(Question); }
private static IEnumerable <string> GetLabels(ref DnStream Stream) { var Labels = new List <string>(); while (true) { var LabelType = Stream.GetBits(2).AsEnum <LabelType>(); switch (LabelType) { case LabelType.Normal: { var Length = Stream.GetBits(6); if (Length == 0) { return(Labels); } var Label = Stream.GetString(Length); Labels.Add(Label); break; } case LabelType.Compressed: { var Pointer = (ushort)(Stream.GetBits(6) + Stream.GetByte()); if (Pointer >= Stream.BytePosition - 2) { throw new ArgumentOutOfRangeException(nameof(Pointer), Pointer, "Compressed Label Infinite Loop Detected."); } var Position = Stream.BytePosition; Stream.Seek(Pointer); Labels.AddRange(GetLabels(ref Stream)); Stream.Seek(Position); return(Labels); } default: throw new ArgumentOutOfRangeException(nameof(LabelType), LabelType, null); } } }
private static IEnumerable <IAnswer> GetAnswers(ref DnStream Stream, ushort Count) { var Answers = new List <IAnswer>(); do { var Answer = GetAnswer(ref Stream); Answers.Add(Answer); }while (Answers.Count < Count); return(Answers); }
private static IEnumerable <IQuestion> GetQuestions(ref DnStream Stream, ushort Count) { var Questions = new List <IQuestion>(); do { var Question = GetQuestion(ref Stream); Questions.Add(Question); }while (Questions.Count < Count); return(Questions); }
private static void Set(ref DnStream Stream, ref Dictionary <string, ushort> Pointers, IAnswer Answer) { Set(ref Stream, ref Pointers, Answer.Domain); Stream.SetUShort((byte)Answer.Type); Stream.SetUShort((byte)Answer.Class); Stream.SetTimeSpan(Answer.TimeToLive); Stream.SetUShort(Answer.Length); Set(ref Stream, ref Pointers, Answer.Record); }
private static IAnswer GetAnswer(ref DnStream Stream) { var Answer = new Answer() { Domain = GetDomain(ref Stream), Type = Stream.GetUShort().AsEnum <RecordType>(), Class = Stream.GetUShort().AsEnum <RecordClass>(), TimeToLive = Stream.GetTimeSpan(), Length = Stream.GetUShort(), }; Answer.Record = GetRecord(ref Stream, Answer.Type); return(Answer); }
public static byte[] Serialize(ref IMessage Message) { var Size = SizeOf(ref Message); var Stream = new DnStream(Size); var Pointers = new Dictionary <string, ushort>(); Stream.SetUShort(Message.ID); Stream.SetBit((byte)Message.MessageType); Stream.SetBits(4, (byte)Message.OperationCode); Stream.SetBit((byte)Message.AuthoritativeAnswer); Stream.SetBit(Convert.ToByte(Message.Truncated)); Stream.SetBit(Convert.ToByte(Message.RecursionDesired)); Stream.SetBit(Convert.ToByte(Message.RecursionAvailable)); Stream.SetBit(Message.Zero); Stream.SetBit(Convert.ToByte(Message.AuthenticatedData)); Stream.SetBit(Convert.ToByte(Message.CheckingDisabled)); Stream.SetBits(4, (byte)Message.ResponseCode); Stream.SetUShort((ushort)Message.Questions.Count()); Stream.SetUShort((ushort)Message.Answers.Count()); Stream.SetUShort((ushort)Message.Authority.Count()); Stream.SetUShort((ushort)Message.Additional.Count()); Set(ref Stream, ref Pointers, Message.Questions); Set(ref Stream, ref Pointers, Message.Answers); Set(ref Stream, ref Pointers, Message.Authority); Set(ref Stream, ref Pointers, Message.Additional); return(Stream.ToArray()); }
private static void Set(ref DnStream Stream, ref Dictionary <string, ushort> Pointers, IEnumerable <string> Labels) { var Domain = string.Join('.', Labels); foreach (var Label in Labels) { var SubDomain = Domain.Substring(Domain.IndexOf(Label)); if (Pointers.ContainsKey(SubDomain)) { Stream.SetBits(2, (byte)LabelType.Compressed); var Bytes = new byte[2]; BinaryPrimitives.WriteUInt16BigEndian(Bytes, Pointers[SubDomain]); Stream.SetBits(6, Bytes[0]); Stream.SetByte(Bytes[1]); return; } else { Pointers.Add(SubDomain, Stream.BytePosition); Stream.SetBits(2, (byte)LabelType.Normal); Stream.SetBits(6, (byte)Label.Length); Stream.SetString(Label); } } Stream.SetByte(0); }
private static void Set(ref DnStream Stream, ref Dictionary <string, ushort> Pointers, IDomain Domain) { Set(ref Stream, ref Pointers, Domain.Labels); }