示例#1
0
        // 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);
                }
            }
        }
示例#2
0
 /// <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);
     }
 }
示例#3
0
        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;
        }
示例#4
0
        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));
        }
示例#5
0
        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;
        }
示例#6
0
        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;
        }
示例#7
0
		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;
		}
示例#8
0
        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;
        }
示例#9
0
        /// <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();
        }
示例#10
0
					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();
					}
示例#11
0
        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");
        }
示例#12
0
        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;
        }
示例#13
0
        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;
        }
示例#14
0
        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;
        }
示例#15
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
        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);
            }
        }
示例#18
0
        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);
        }
示例#19
0
        // 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);
        }
示例#20
0
        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);
        }
示例#21
0
        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);
        }
示例#22
0
        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.");
            }
        }
示例#23
0
        /// <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));
        }
示例#24
0
        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);
        }
示例#25
0
        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;
        }
示例#26
0
        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);
        }