// NsSearch // // Executes a query for the SOA from the local or specified DNS server. // Executes a query for the NS records from the SOA. // Performs the query on each listed Name Server. internal void NsSearch(String Name, String Server) { String Domain = Name; Boolean HasSOA = false; Boolean NoError = true; do { Lookup(Domain, RecordType.SOA, Server, false); DnsPacket Message = (DnsPacket)ResponseMessages[0]; if (Message.Header.RCode == RCode.NoError) { foreach (ResourceRecord Answer in Message.Answer) { if (Answer.RecordType == RecordType.SOA) { SOA SOARecord = (SOA)Answer; HasSOA = true; Server = SOARecord.TargetName; } } if (!HasSOA) { // Remove a label and retry. if (Domain.Contains(".")) { Domain = Domain.Substring(Domain.IndexOf('.') + 1, Domain.Length - Domain.IndexOf('.') - 1); } else { NoError = false; } } } else { NoError = false; } } while (!HasSOA & NoError); // Get the list of name servers from the SOA if (HasSOA) { Lookup(Domain, RecordType.NS, Server, false); Object[] NameServers = ((DnsPacket)ResponseMessages[0]).Answer; // Get the answer for Name from each Authoritative Server foreach (ResourceRecord NameServer in NameServers) { Server = NameServer.RecordData; Lookup(Name, RecordType, Server, true); } } }
/// <summary> /// 添加应用层协议 /// </summary> /// <param name="payloadData">载荷数据</param> /// <param name="SourcePort">源端口</param> /// <param name="DestinationPort">目的端口</param> private void AppNode(byte[] payloadData, ushort SourcePort, ushort DestinationPort) { if (payloadData.Length == 0) { return; } AppsrcPort = SourcePort; AppdstPort = DestinationPort; //HTTP 80 if (isAnalysProtocol(80)) { HttpPacket http = new HttpPacket(payloadData); Http(http); } //smtp 25 else if (isAnalysProtocol(25)) { SmtpPacket smtp = new SmtpPacket(payloadData); SMTP(smtp); } //pop3 110 else if (isAnalysProtocol(110)) { Pop3Packet pop3 = new Pop3Packet(payloadData); POP3(pop3); } //DNS 53 else if (isAnalysProtocol(53)) { DnsPacket dns = new DnsPacket(payloadData); DNS(dns); } //ftp 21 else if (isAnalysProtocol(21)) { FtpPacket ftp = new FtpPacket(payloadData); FTP(ftp); } //DHCP 67 68 else if (isAnalysProtocol(67) || isAnalysProtocol(68)) { DhcpPackets dp = new DhcpPackets(payloadData); DHCP(dp); } else if (isAnalysProtocol(520)) { RipPacket rp = new RipPacket(payloadData); RIP(rp); } //ssdp 1900 else if (isAnalysProtocol(1900)) { SSDPPacket ssdp = new SSDPPacket(payloadData); SSDP(ssdp); } }
public void ParseResponseFrom114() { DnsPacket dnsPacket = new DnsPacket(new KaitaiStream(udpPackets[3].PayloadData)); const string StrAddressExpected = "2001::1f0d:4c10"; const int N_TTL_Expected = 89; VerifyAnswer(dnsPacket, StrAddressExpected, N_TTL_Expected); return; }
private byte[] FindCachedAnswerOrResend(DnsPacket query, Dictionary <string, DnsPacket> subCache) { if (TryModifyCache(query, out var cachedPacket)) { return(UpdatePacketFromCache(cachedPacket, query.TransactionId)); } return(subCache.TryGetValue(query.Questions[0].Name, out cachedPacket) ? UpdatePacketFromCache(cachedPacket, query.TransactionId) : GetAnswerFromBetterServer(query.Data, subCache)); }
public void ParseResponseFrom8() { DnsPacket dnsPacket = new DnsPacket(new KaitaiStream(udpPackets[3].PayloadData)); const string StrAddressExpected = "95.211.219.67"; const int N_TTL_Expected = 599; VerifyAnswer(dnsPacket, StrAddressExpected, N_TTL_Expected); return; }
public void ParseResponseFrom114() { DnsPacket dnsPacket = new DnsPacket(new KaitaiStream(udpPackets[2].PayloadData)); const string StrAddressExpected = "69.162.80.55"; const int N_TTL_Expected = 600; VerifyAnswer(dnsPacket, StrAddressExpected, N_TTL_Expected); return; }
public async Task<IPAddress[]> ResolveAsync(string hostname, int timeout = 2000) { IPEndPoint mdnsEndPoint = new IPEndPoint(MulticastAddress, Port); UdpClient client = new UdpClient(); DnsPacket questionPacket = new DnsPacket(); if (!hostname.EndsWith(HostnameSuffix)) { hostname += HostnameSuffix; } questionPacket.Questions.Add(new DnsQuestion(hostname, DnsRecordType.A, DnsRecordClass.InterNetwork)); byte[] data = questionPacket.ToBytes(); client.JoinMulticastGroup(MulticastAddress); client.Send(data, data.Length, mdnsEndPoint); client.Client.ReceiveTimeout = timeout; DateTime endTime = DateTime.Now + new TimeSpan(0, 0, 0, 0, timeout); CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(timeout); while (DateTime.Now < endTime) { UdpReceiveResult receiveTask = await Task.Run(client.ReceiveAsync, cancellationTokenSource.Token); DnsPacket responsePacket = DnsPacket.FromBytes(receiveTask.Buffer); if (responsePacket.ID == questionPacket.ID && responsePacket.AnswerCount > 0) { List<IPAddress> results = new List<IPAddress>(); foreach (var answer in responsePacket.Answers) { DnsARecord aRecord = answer as DnsARecord; if (aRecord != null) { results.Add(aRecord.IPAddress); } } if (results.Count > 0) { return results.ToArray(); } } } return null; }
public void ParseInvalidRefNameLength() { // Modify name segment length to exceed packet data end // offset 36, 0xC0, -> pointer, offset 0 << 8 + data[37] // offset 37, 0x0C, -> begining of name in header, 'china' // modify offset as 24, so that offset + length >= data size, i.e. 36 byte[] byteData = udpPackets[2].PayloadData; Assert.IsTrue(0xC0 == byteData[36]); Assert.IsTrue(0x0C == byteData[37]); byteData[36] = 0xC1; byteData[37] = (byte)byteData.Length; //try { DnsPacket dnsPacket = new DnsPacket(new KaitaiStream(byteData)); DnsPacket.Query q = dnsPacket.Body.Queries[0]; VerifyName(q.Name.Name, StrQueryDomainName); DnsPacket.Answer a = dnsPacket.Body.Answers[0]; Assert.IsTrue(DnsPacket.ClassType.InClass == a.AnswerClass); Assert.IsTrue(600 == a.Ttl); Assert.IsTrue(DnsPacket.TypeType.A == a.Type); //VerifyRefName(a.Name.Name); { Assert.AreEqual((int)1, a.Name.Name.Count); Label l = a.Name.Name[0]; Assert.IsTrue(l.IsPointer); Assert.IsTrue(0xC1 == l.Length); Assert.IsTrue(byteData.Length == l.Pointer.Value); PointerStruct ps = l.Pointer; try { VerifyName(ps.Contents.Name, StrQueryDomainName); } catch (System.IO.EndOfStreamException) { Assert.IsTrue(true); } } } //catch (System.IO.EndOfStreamException) { Assert.IsTrue(true); } return; }
/// <summary> /// Write the text representation of <see cref="DnsPacket"/>. It uses Flix assert format, e.g., Frame(DnsPacket(0.1, 1234, Query)). /// </summary> /// <param name="packet"></param> public void WriteRecord(PosixTimeval timestamp, FlowKey flowKey, DnsPacket packet) { string answerString(DnsPacket.Answer answer) { switch (answer.Rdata) { case DnsPacket.ARecord a: return($"A(\"{answer.Name.DomainNameString}\",\"{new IPAddress(a.Address)}\")"); case DnsPacket.AaaaRecord aaaa: return($"AAAA(\"{answer.Name.DomainNameString}\",\"{new IPAddress(aaaa.Address)}\")"); case DnsPacket.CnameRecord cname: return($"CNAME(\"{answer.Name.DomainNameString}\",\"{cname.Hostname.DomainNameString}\")"); case DnsPacket.NsRecord ns: return($"NS(\"{answer.Name.DomainNameString}\",\"{ns.Hostname.DomainNameString}\")"); case DnsPacket.MxRecord mx: return($"NS(\"{answer.Name.DomainNameString}\",{mx.Priority},\"{mx.Hostname.DomainNameString}\")"); default: return("NULL"); } } var ts = ((double)timestamp.Seconds + ((double)timestamp.MicroSeconds) / 1000000).ToString("0.000"); var id = packet.TransactionId; var rcode = packet.Flags.Rcode == 0 ? "NoError" : "NameDoesNotExist"; var queries = String.Join("::", packet.Queries.Select(x => $"{x.Type.ToString().ToUpperInvariant()}(\"{x.Name.DomainNameString}\",\"\")").Append("Nil")); var answers = String.Join("::", packet.Answers.Select(answerString).Append("Nil")); var qr = packet.Flags.Qr == 0 ? $"Query({id},{queries})" : $"Response({id},{rcode},{queries},{answers})"; var dns = $"DNS({qr})"; var proto = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(flowKey.Protocol.ToString()); var ipSrc = flowKey.SourceEndpoint.Address.ToString(); var ipDst = flowKey.DestinationEndpoint.Address.ToString(); var portSrc = flowKey.SourceEndpoint.Port; var portDst = flowKey.DestinationEndpoint.Port; var flow = $"{proto}(\"{ipSrc}\",\"{ipDst}\",{portSrc},{portDst})"; // Frame(1520329507.498, Udp("192.168.111.100", "147.229.9.43", 1234, 53), DnsPacket(Query(15595,A("api.github.com.", "")::Nil))). var str = $"Frame({ts}, {flow}, {dns})."; m_writer.WriteLine(str); m_writer.Flush(); }
public static RecordPTR[] Get(IPAddress target, IPAddress dnsServer, IPAddress localAddress, int attempts = 2, int timeout = 1000) { if (dnsServer.AddressFamily != localAddress.AddressFamily) throw new CfnIpFamilyMismatchException(); var requestPacket = new DnsPacket(); requestPacket.Header.RecursionDesired = true; requestPacket.Questions = new[] {new DnsLlmnrQuestion {Name = target.GetAddrArpaString(), Type = DnsLlmnrCodes.QTypes.PTR}}; var responsePacket = requestPacket.Send(dnsServer, 53, localAddress, attempts, timeout); if (responsePacket.Header.RCode != DnsLlmnrCodes.RCodes.NoError && responsePacket.Header.RCode != DnsLlmnrCodes.RCodes.NxDomain) throw new CfnException(responsePacket.Header.RCode.GetThrowMessage()); return responsePacket.Answers.Where(x => x.Type == DnsLlmnrCodes.RrTypes.PTR).Select(x => ((RecordPTR) x.Record)).ToArray(); }
private static void VerifyAnswer(DnsPacket dnsPacket, string StrAddressExpected, int ttl) { Assert.AreEqual(dnsPacket.TransactionId, (ushort)0x0006); //Assert.AreEqual((ushort)0x8180, dnsPacket.Flags.Flag); Assert.IsTrue(dnsPacket.Flags.IsOpcodeValid); Assert.IsTrue(dnsPacket.Flags.Rd); Assert.IsTrue(dnsPacket.Flags.Qr); Assert.IsTrue(dnsPacket.Flags.Ra); Assert.AreEqual((ushort)1, dnsPacket.Body.Qdcount); Assert.AreEqual((ushort)1, dnsPacket.Body.Ancount); Assert.AreEqual(1, dnsPacket.Body.Nscount); Assert.AreEqual(0, dnsPacket.Body.Arcount); Assert.IsTrue(1 == dnsPacket.Body.Queries.Count); Assert.IsTrue(1 == dnsPacket.Body.Answers.Count); Assert.IsTrue(1 == dnsPacket.Body.Authorities.Count); DnsPacket.Query q = dnsPacket.Body.Queries[0]; Assert.IsTrue(DnsPacket.TypeType.Aaaa == q.Type); Assert.IsTrue(DnsPacket.ClassType.InClass == q.QueryClass); VerifyName(q.Name.Name, StrQueryDomainName); DnsPacket.Answer a = dnsPacket.Body.Answers[0]; Assert.AreEqual(DnsPacket.ClassType.InClass, a.AnswerClass); Assert.AreEqual(ttl, a.Ttl); Assert.AreEqual(DnsPacket.TypeType.Cname, a.Type); VerifyRefName(a.Name.Name); DnsPacket.Answer ns = dnsPacket.Body.Authorities[0]; Assert.AreEqual(DnsPacket.ClassType.InClass, ns.AnswerClass); Assert.AreEqual(37, ns.Ttl); Assert.AreEqual(DnsPacket.TypeType.Soa, ns.Type); Assert.AreEqual(53, ns.Rdlength); Assert.AreEqual(ns.Payload.GetType(), typeof(DnsPacket.AuthorityInfo)); Assert.AreEqual(ns.Name.GetFullName(), "github.com"); DnsPacket.AuthorityInfo nsInfo = (DnsPacket.AuthorityInfo)ns.Payload; Assert.AreEqual(nsInfo.ExpireLimit, (uint)604800); Assert.AreEqual(nsInfo.MinTtl, (uint)60); Assert.AreEqual(nsInfo.Serial, (uint)1592319081); Assert.AreEqual(nsInfo.RetryInterval, (uint)600); Assert.AreEqual(nsInfo.RefreshInterval, (uint)3600); VerifyName(nsInfo.PrimaryNs.Name, "ns1.p16.dynect.net"); Assert.AreEqual(nsInfo.ResoponsibleMailbox.GetFullName(), "hostmaster.github.com"); }
public void ParseRequest() { DnsPacket dnsPacket = new DnsPacket(new KaitaiStream(udpPackets[1].PayloadData)); Assert.AreEqual(dnsPacket.TransactionId, (ushort)0x1622); //Assert.AreEqual((ushort)0x0100, dnsPacket.Flags.Flag); Assert.IsTrue(dnsPacket.Flags.IsOpcodeValid); Assert.IsTrue(dnsPacket.Flags.Rd); Assert.AreEqual((ushort)1, dnsPacket.Body.Qdcount); Assert.IsTrue(0 == dnsPacket.Body.Arcount); Assert.IsTrue(0 == dnsPacket.Body.Ancount); Assert.IsTrue(0 == dnsPacket.Body.Nscount); Assert.AreEqual((ushort)1, dnsPacket.Body.Queries.Count); DnsPacket.Query q = dnsPacket.Body.Queries[0]; Assert.AreEqual(DnsPacket.TypeType.Aaaa, q.Type); Assert.AreEqual(DnsPacket.ClassType.InClass, q.QueryClass); Assert.AreEqual(q.Name.GetFullName(), StrQueryDomainName); return; }
public void ParseRequest() { DnsPacket dnsPacket = new DnsPacket(new KaitaiStream(udpPackets[8].PayloadData)); Assert.IsTrue(dnsPacket.TransactionId == 0x000a); //Assert.IsTrue(0x0100 == dnsPacket.Flags.Flag); Assert.IsTrue(dnsPacket.Flags.IsOpcodeValid); Assert.IsTrue(dnsPacket.Flags.Rd); Assert.IsTrue(1 == dnsPacket.Body.Qdcount); Assert.IsTrue(0 == dnsPacket.Body.Arcount); Assert.IsTrue(0 == dnsPacket.Body.Ancount); Assert.IsTrue(0 == dnsPacket.Body.Nscount); Assert.IsTrue(1 == dnsPacket.Body.Queries.Count); DnsPacket.Query q = dnsPacket.Body.Queries[0]; Assert.IsTrue(DnsPacket.TypeType.Mx == q.Type); Assert.IsTrue(DnsPacket.ClassType.InClass == q.QueryClass); VerifyName(q.Name.Name, StrQueryDomainName); return; }
public void ParseInvalidNameLabel() { // Modify name segment length to exceed packet data end // offset 12, 0x05, -> length of 'china' // modify as 24, so that offset + length >= data size, i.e. 36 byte[] byteData = udpPackets[0].PayloadData; Assert.IsTrue(0x05 == byteData[12]); byteData[12] = 24; try { DnsPacket dnsPacket = new DnsPacket(new KaitaiStream(byteData)); Assert.Fail("Invalid packet data passed"); } catch (System.IO.EndOfStreamException) { Assert.IsTrue(true); } return; }
private byte[] HandleRequest(byte[] data) { var query = new DnsPacket(data); Console.WriteLine($"GOT:\n{query}"); if (!query.IsQuery) { return(null); } foreach (var question in query.Questions) { if (SupportedTypes.Contains(question.Type)) { return(FindCachedAnswerOrResend(query, cache[question.Type])); } Console.WriteLine($"Message with the type code {question.Type} is not currently supported!"); } return(null); }
private IEnumerable <Model.DnsObject> ExtractDnsObjects(System.Net.IPEndPoint client, System.Net.IPEndPoint server, string flowId, IEnumerable <FrameData> packetList) { var result = new List <DnsObject>(); foreach (var frame in packetList) { try { var packet = Packet.ParsePacket((LinkLayers)frame.LinkLayer, frame.Data); var udpPacket = packet.Extract(typeof(UdpPacket)) as UdpPacket; var stream = new KaitaiStream(udpPacket.PayloadData); var dnsPacket = new DnsPacket(stream); var clientString = client.ToString(); var serverString = server.ToString(); foreach (var(answer, index) in dnsPacket.Answers.Select((x, i) => (x, i + 1))) { var dnsObject = new Model.DnsObject { Client = clientString, Server = serverString, Timestamp = frame.Timestamp, FlowUid = flowId, TransactionId = $"{dnsPacket.TransactionId.ToString("X4")}-{index.ToString("D4")}", DnsType = answer.Type.ToString().ToUpperInvariant(), DnsTtl = answer.Ttl, DnsQuery = answer.Name.DomainNameString, DnsAnswer = answer.AnswerString, }; result.Add(dnsObject); } } catch (Exception e) { m_ignite.Logger.Log(Apache.Ignite.Core.Log.LogLevel.Error, "ExtractDnsObjects error", null, null, "Error", "", e); } } return(result); }
private byte[] GetAnswerFromBetterServer(byte[] query, Dictionary <string, DnsPacket> subCache) { using (var client = new UdpClient()) { client.Client.ReceiveTimeout = 2000; client.Send(query, query.Length, remoteDns); byte[] response; try { response = client.Receive(ref remoteDns); } catch (SocketException) { ConsolePainter.WriteWarning("Couldn't connect to the upper server. Check internet connection"); return(null); } var responsePacket = new DnsPacket(response); ConsolePainter.WriteResponse($"SENDING:\n{responsePacket}"); subCache[responsePacket.Questions[0].Name] = responsePacket; return(response); } }
public override UdpPacket Translate(UdpPacket packet, MemBlock source_ip, MemBlock old_source_ip, MemBlock old_dest_ip) { DnsPacket dnsp = new DnsPacket(packet.Payload); String ss_ip = DnsPacket.IPMemBlockToString(source_ip); bool change = mDnsTranslate(dnsp.Answers, ss_ip); change |= mDnsTranslate(dnsp.Authority, ss_ip); change |= mDnsTranslate(dnsp.Additional, ss_ip); // If we make a change let's make a new packet! if (change) { dnsp = new DnsPacket(dnsp.ID, dnsp.Query, dnsp.Opcode, dnsp.AA, dnsp.RA, dnsp.RD, dnsp.Questions, dnsp.Answers, dnsp.Authority, dnsp.Additional); return(new UdpPacket(packet.SourcePort, packet.DestinationPort, dnsp.ICPacket)); } //not a mDns packet after all? return(packet); }
// Incremental Zone Transfer // // Get the current SOA, modify the serial and send the request. internal void IXFRLookup(String Name, UInt32 Serial, String Server) { this.Tcp = false; Lookup(Name, RecordType.SOA, Server, false); // Use the server returned by the SOA as a target for the query DnsPacket Message = (DnsPacket)ResponseMessages[0]; SOA SOARecord = new SOA(Name, Serial); Header DnsHeader = new Header(false, 1); DnsHeader.AuthorityCount = 1; Question DnsQuestion = new Question(Name, RecordType.IXFR); Byte[] Payload = CreatePayload(DnsHeader, DnsQuestion); Payload = AddAuthority(Payload, SOARecord); // Clear old responses ResponseMessages.Clear(); this.Tcp = true; ExecuteLookup(Payload, RecordType.IXFR, Server, true); }
private bool TryModifyCache(DnsPacket query, out DnsPacket cached) { var question = query.Questions[0]; if (cache[question.Type].TryGetValue(question.Name, out cached)) { ConsolePainter.WriteResponse($"MESSAGE FROM CACHE:\n{cached}"); return(true); } if (TryFindRightCachedRecord(query, out cached)) { var gen = DnsPacket.GenerateAnswer(query.TransactionId, query.Questions, question.Type == ResourceType.A ? cached.AdditionalRecords : cached.AuthoritiveServers); ConsolePainter.WriteResponse($"Modified from cache:\n{gen}"); cached = gen; cache[query.Questions[0].Type].Add(query.Questions[0].Name, gen); return(true); } cached = null; return(false); }
private bool TryFindRightCachedRecord(DnsPacket query, out DnsPacket cached) { var aRecords = cache[ResourceType.A]; var questions = query.Questions.Select(q => q.Name).ToList(); bool IsCorrectRecord(List <ResourseRecord> rec) { return(rec.Count != 0 && questions.Intersect(rec.Select(k => k.Name)) .Any()); } foreach (var kvp in aRecords) { if (!IsCorrectRecord(kvp.Value.AdditionalRecords) && !IsCorrectRecord(kvp.Value.AuthoritiveServers)) { continue; } cached = kvp.Value; return(true); } cached = null; return(false); }
private static void Device_OnPacketArrival(object sender, CaptureEventArgs e) { try { var packet = Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data); var ip = packet.Extract(typeof(IpPacket)) as IpPacket; var udp = packet.Extract(typeof(UdpPacket)) as UdpPacket; var flowKey = new FlowKey() { Protocol = ProtocolType.UDP, SourceEndpoint = new System.Net.IPEndPoint(ip.SourceAddress, udp.SourcePort), DestinationEndpoint = new System.Net.IPEndPoint(ip.DestinationAddress, udp.DestinationPort) }; var str = new KaitaiStream(udp.PayloadData); var dns = new DnsPacket(str); outputFormatter.WriteRecord(e.Packet.Timeval, flowKey, dns); } catch (Exception ex) { Console.Error.WriteLine($"{e.Packet.Timeval.Date}: Unable to parse packet."); } }
/// <summary>Look up a hostname given a Dns request in the form of IPPacket /// </summary> /// <param name="in_ip">An IPPacket containing the Dns request</param> /// <returns>An IPPacket containing the results</returns> public virtual IPPacket LookUp(IPPacket in_ip) { UdpPacket in_udp = new UdpPacket(in_ip.Payload); DnsPacket in_dns = new DnsPacket(in_udp.Payload); ICopyable out_dns = null; string qname = string.Empty; bool invalid_qtype = false; try { string qname_response = String.Empty; qname = in_dns.Questions[0].QName; DnsPacket.Types type = in_dns.Questions[0].QType; if (type == DnsPacket.Types.A || type == DnsPacket.Types.AAAA) { qname_response = AddressLookUp(qname); } else if (type == DnsPacket.Types.Ptr) { qname_response = NameLookUp(qname); } else { invalid_qtype = true; } if (qname_response == null) { throw new Exception("Unable to resolve"); } Response response = new Response(qname, in_dns.Questions[0].QType, in_dns.Questions[0].QClass, 1800, qname_response); //Host resolver will not accept if recursive is not available //when it is desired DnsPacket res_packet = new DnsPacket(in_dns.ID, false, in_dns.Opcode, true, in_dns.RD, in_dns.RD, in_dns.Questions, new Response[] { response }, null, null); out_dns = res_packet.ICPacket; } catch (Exception e) { bool failed_resolve = false; // The above resolver failed, let's see if another resolver works if (_forward_queries) { try { out_dns = Resolve(_name_server, (byte[])in_dns.Packet); } catch (Exception ex) { e = ex; failed_resolve = true; } } if (!_forward_queries || failed_resolve) { ProtocolLog.WriteIf(IpopLog.Dns, "Failed to resolve: " + qname + "\n\t" + e.Message); out_dns = DnsPacket.BuildFailedReplyPacket(in_dns, !invalid_qtype); } } UdpPacket out_udp = new UdpPacket(in_udp.DestinationPort, in_udp.SourcePort, out_dns); return(new IPPacket(IPPacket.Protocols.Udp, in_ip.DestinationIP, in_ip.SourceIP, out_udp.ICPacket)); }
internal void ExecuteLookup(Byte[] Payload, RecordType RecordType, String Server, Boolean DisplayResponse) { EndPoint RemoteEndPoint = this.CreateRemoteEndPoint(Server); Socket DnsClient = this.CreateSocket(RemoteEndPoint.AddressFamily); Byte[] ReceiveBuffer = new Byte[ResponseBufferSize]; if (this.Tcp) { DateTime Start = DateTime.Now; Payload = PrefixLength(Payload); DnsClient.Connect(RemoteEndPoint); if (DnsClient.Connected) { DnsClient.Send(Payload); } ArrayList ResponseBytes = new ArrayList(); Boolean IsAXFR = false; Boolean IsIXFR = false; UInt32 Serial = 0; UInt32 SOACount = 0; Boolean Complete = false; do { Boolean CanReadReply = true; Int32 NumberOfBytesReceived = DnsClient.Receive(ReceiveBuffer); // Copy the received bytes into an ArrayList Byte[] ReceivedBytes = new Byte[NumberOfBytesReceived]; Array.Copy(ReceiveBuffer, ReceivedBytes, NumberOfBytesReceived); // Add the contents of this packet to ResponseBytes ResponseBytes.AddRange(ReceivedBytes); while (ResponseBytes.Count > 2 & CanReadReply) { Int32 ResponseLength = ((Int32)(Byte)ResponseBytes[0] << 8) | (Int32)(Byte)ResponseBytes[1]; if (ResponseBytes.Count >= ResponseLength + 2) { DnsPacket Message = new DnsPacket((Byte[])ResponseBytes.GetRange(2, ResponseLength).ToArray(typeof(Byte))); Message.Server = Server; Message.TimeTaken = (DateTime.Now - Start).TotalMilliseconds; ResponseMessages.Add(Message); if (DisplayResponse) { WriteObject(Message); } ResponseBytes.RemoveRange(0, ResponseLength + 2); if (Message.Header.RCode != RCode.NoError) { Complete = true; } else { switch (RecordType) { case RecordType.IXFR: // See if the transfer type has switched to AXFR if (!IsIXFR & !IsAXFR) { if (ResponseMessages.Count == 1) { if (Message.Header.AnswerCount > 1) { if ((Message.Answer[1]).RecordType == RecordType.SOA) { IsIXFR = true; if (((SOA)Message.Answer[1]).Serial == Serial) { Complete = true; } } else { RecordType = RecordType.AXFR; IsAXFR = true; } } } else if (ResponseMessages.Count == 2) { if ((Message.Answer[0]).RecordType == RecordType.SOA) { IsIXFR = true; } else { RecordType = RecordType.AXFR; IsAXFR = true; } } } if (Serial == 0 & ResponseMessages.Count == 1) { Serial = ((SOA)Message.Answer[0]).Serial; if (Incremental > Serial) { Complete = true; } } foreach (ResourceRecord Answer in Message.Answer) { if (Answer.RecordType == RecordType.SOA) { if (((SOA)Answer).Serial == Serial) { SOACount++; } } } if (SOACount == 3 & IsIXFR) { Complete = true; } if (SOACount == 2 & IsAXFR) { Complete = true; } break; case RecordType.AXFR: if (ResponseMessages.Count == 1 & Message.Header.AnswerCount > 1) { if ((Message.Answer[Message.Header.AnswerCount - 1]).RecordType == RecordType.SOA) { Complete = true; } } else if (ResponseMessages.Count > 1) { if ((Message.Answer[Message.Header.AnswerCount - 1]).RecordType == RecordType.SOA) { Complete = true; } } break; default: Complete = true; break; } } } else { CanReadReply = false; } } } while (!Complete); } else { DateTime Start = DateTime.Now; DnsClient.SendTo(Payload, RemoteEndPoint); EndPoint Sender = (EndPoint) new IPEndPoint(IPAddress.Any, 0); Int32 NumberOfBytesReceived = DnsClient.ReceiveFrom(ReceiveBuffer, ref Sender); Byte[] Response = new Byte[NumberOfBytesReceived]; Array.Copy(ReceiveBuffer, Response, NumberOfBytesReceived); DnsPacket Message = new DnsPacket(Response); Message.Server = Server; Message.TimeTaken = (DateTime.Now - Start).TotalMilliseconds; ResponseMessages.Add(Message); if (DisplayResponse) { WriteObject(Message); } } this.CloseSocket(DnsClient); }
public void ParseLoopRefNameOffset() { // Modify name segment length to exceed packet data end // offset 36, 0xC0, -> pointer, offset 0 << 8 + data[37] // offset 37, 0x0C, -> begining of name in header, 'china' // modify offset as 24, so that offset + length >= data size, i.e. 36 byte[] byteData = udpPackets[2].PayloadData; Assert.IsTrue(0xC0 == byteData[36]); Assert.IsTrue(0x0C == byteData[37]); byteData[36] = 0xC0; byteData[37] = 36; //try { DnsPacket dnsPacket = new DnsPacket(new KaitaiStream(byteData)); DnsPacket.Query q = dnsPacket.Body.Queries[0]; VerifyName(q.Name.Name, StrQueryDomainName); DnsPacket.Answer a = dnsPacket.Body.Answers[0]; Assert.IsTrue(DnsPacket.ClassType.InClass == a.AnswerClass); Assert.IsTrue(600 == a.Ttl); Assert.IsTrue(DnsPacket.TypeType.A == a.Type); //VerifyRefName(a.Name.Name); { Assert.AreEqual((int)1, a.Name.Name.Count); Label l = a.Name.Name[0]; Assert.IsTrue(l.IsPointer); Assert.IsTrue(0xC0 == l.Length); Assert.IsTrue(36 == l.Pointer.Value); PointerStruct ps = l.Pointer; try { //VerifyName(ps.Contents.Name, StrQueryDomainName); Assert.AreEqual(1, ps.Contents.Name.Count); Label l2 = ps.Contents.Name[0]; Assert.AreEqual(true, l2.IsPointer); Assert.AreEqual(0xC0, l2.Length); Assert.AreEqual((byte)36, l2.Pointer.Value); } catch (Exception) { Assert.Fail(); } // Try to get full name will cause exception try { Assert.AreEqual(a.Name.GetFullName(), ""); Assert.Fail("Exception expected"); } catch (ArgumentOutOfRangeException e) { Console.WriteLine("Exception expected in detecting ref loop: {0}", e.Message); } } } //catch (System.IO.EndOfStreamException) { Assert.IsTrue(true); } return; }
private void DNS(DnsPacket dns) { if (dns == null) { return; } if (DnsNode == null) { DnsNode = CreatNode("DNS", 7); } DnsNode.Nodes.Clear(); DnsNode.Nodes.Add("Transaction ID: [0x" + dns.ID.ToString("X4") + "]"); #region Flags if (dnsFlagsNode == null) { dnsFlagsNode = new TreeNode(); } dnsFlagsNode.Nodes.Clear(); dnsFlagsNode.Text = "Flags: [0x" + dns.Flags.ToString("X4") + "]"; string quMsg = (dns.QR == 0) ? "Message is a query" : "Message is a response"; dnsFlagsNode.Nodes.Add(dns.QR.ToString() + "... .... .... .... = Response: " + quMsg); string opCodeStr = Convert.ToString(dns.OpCode, 2).PadLeft(4, '0').Insert(3, " "); string opcodeResult = ""; switch (dns.OpCode) { case 0: opcodeResult = "Standar Query"; break; case 1: opcodeResult = "Opposite Query"; break; case 2: opcodeResult = "Server status Query"; break; default: opcodeResult = "Undefined"; break; } dnsFlagsNode.Nodes.Add("." + opCodeStr + "... .... .... = OpCode: " + opcodeResult + " (" + dns.OpCode + ")"); string AAStr = (dns.AA == 0) ? "Server is not an authority for aomain" : "Server is an authority for aomain"; dnsFlagsNode.Nodes.Add(".... ." + dns.AA + ".. .... .... = Authoritative: " + AAStr); string trcStr = (dns.TC == 0) ? "Message is No truncated" : "Message is truncated"; dnsFlagsNode.Nodes.Add(".... .." + dns.TC + ". .... .... = Truncated: " + trcStr); string RdStr = (dns.RD == 0) ? " Don't do query recursively" : "Do query recursively"; dnsFlagsNode.Nodes.Add(".... ..." + dns.RD + " .... .... = Recursion desired: " + RdStr); string RaStr = (dns.RA == 0) ? "Server can do recursive queries" : "Server can't do recursive queries"; dnsFlagsNode.Nodes.Add(".... .... " + dns.RA + "... .... = Recursion avaiable: " + RaStr); #warning 此处可能已经定义,以后希望修改 dnsFlagsNode.Nodes.Add(".... .... .000 .... = Reserved bits"); string rcodeStr = ""; switch (dns.rCode) { case 0: rcodeStr = "No error"; break; case 1: rcodeStr = "Format error"; break; case 2: rcodeStr = "Dns server error"; break; case 3: rcodeStr = "Domain parameters error"; break; case 4: rcodeStr = "type is not supported"; break; case 5: rcodeStr = "Management banned"; break; default: rcodeStr = "Undefined"; break; } string dnsRCodestr = Convert.ToString(dns.rCode, 2).PadLeft(4, '0'); dnsFlagsNode.Nodes.Add(".... .... .... " + dnsRCodestr + " = Reply code: " + rcodeStr + " (" + dns.rCode + ")"); DnsNode.Nodes.Add(dnsFlagsNode); #endregion DnsNode.Nodes.Add("Questions: " + dns.QusetionCounts); DnsNode.Nodes.Add("Answer RRs: " + dns.AnswerCounts); DnsNode.Nodes.Add("Authority RRs: " + dns.AuthorityCounts); DnsNode.Nodes.Add("Additional RRs: " + dns.AdditionalCounts); #region Query Part if (dnsQueryNode == null) { dnsQueryNode = new TreeNode(); dnsQueryNode.Text = "Questions"; } TwzyProtocol.DNS.DnsQuery dnsQuery = dns.Query; dnsQueryNode.Nodes.Clear(); if (dnsQuery != null) { dnsQueryNode.Name = "DNS_QU"; dnsQueryNode.Text = "Questions [Name=" + dnsQuery.name + "] [Type=" + dnsQuery.DnsType + "] [Class=" + dnsQuery.DnsClass + "]"; dnsQueryNode.Nodes.Add("Name: " + dnsQuery.name); dnsQueryNode.Nodes.Add("Type: " + dnsQuery.DnsType + " [0x" + dnsQuery.DnsType.ToString("X") + "]"); dnsQueryNode.Nodes.Add("Class: " + dnsQuery.DnsClass + " [0x" + dnsQuery.DnsClass.ToString("X") + "]"); } else { dnsQueryNode.Nodes.Add("Error Data: " + Encoding.ASCII.GetString(dns.ErrData)); } DnsNode.Nodes.Add(dnsQueryNode); #endregion #region Response Parts List <TwzyProtocol.DNS.DnsResponse> relist = null; if (dns.QR == 1 && dnsQuery != null) { relist = dns.ResponseList; if (dnsAnswerNodeList == null) { dnsAnswerNodeList = new List <TreeNode>(); } dnsAnswerNodeList.Clear(); foreach (var k in relist) { TreeNode reNode = new TreeNode(); reNode.Name = "DNS_AN"; reNode.Text = k.AnswerType.ToString() + " [Name=" + k.name + "] [Type=" + k.dnsType + "] [Class=" + k.dnsClass + "] [Legth=" + k.payLength.ToString() + "bytes] [TTL=" + k.TTL.ToString() + "s] [Address=" + k.rescData + "]"; reNode.Nodes.Add("Name: " + k.name); reNode.Nodes.Add("Type: " + k.dnsType + " [0x" + k.dnsType.ToString("X") + "]"); reNode.Nodes.Add("Class: " + k.dnsClass + " [0x" + k.dnsClass.ToString("X") + "]"); reNode.Nodes.Add("TTL: " + k.TTL.ToString() + "s"); reNode.Nodes.Add("Data Length: " + k.payLength.ToString()); reNode.Nodes.Add("Address: " + k.rescData); dnsAnswerNodeList.Add(reNode); } DnsNode.Nodes.AddRange(dnsAnswerNodeList.ToArray()); } #endregion Tree.Nodes.Add(DnsNode); }