/// <summary> /// Function that processes the incoming data after an async callback returned. /// </summary> /// <param name="endpoint">The endpoint the data came from</param> /// <param name="Data">The dns packet data</param> /// <returns></returns> private bool DNSRequestHandler(EndPoint endpoint, byte[] Data) { //take out the headers, decide where to send it into the processor. if (Processor.IsDNSRequest(Data)) { DNSPacket packet = DNSPacket.RawToPacket(Data); if (packet.Type == DNSPacket.PacketType.Request) { string lookupData = Encoding.ASCII.GetString(packet.Data, 0, packet.Length); switch (packet.Lookup) { case DNSPacket.LookupType.Name: return(SendResponse(endpoint, packet.Lookup, Processor.LookupByName(lookupData.Split('.').Reverse().ToArray()))); case DNSPacket.LookupType.ARPA: return(SendResponse(endpoint, packet.Lookup, Processor.LookupByIp(lookupData))); } } else { throw new DNSException(packet, "Received a Response package while expecting only Request packages."); } } return(false); }
/// <summary> /// Function that sends the async responses to the client. /// </summary> /// <param name="endpoint">The endpoint to send the response to</param> /// <param name="type">Packet type</param> /// <param name="record">The DNSRecord to send back</param> /// <returns></returns> private bool SendResponse(EndPoint endpoint, DNSPacket.LookupType type, DNSRecord record) { if (record == null) { return(false); } DNSPacket packet = new DNSPacket { Type = DNSPacket.PacketType.Response, Lookup = type, Data = (type == DNSPacket.LookupType.Name) ? Encoding.ASCII.GetBytes(record.Address) : Encoding.ASCII.GetBytes(string.Join(",", record.SubDomains.Select(n => n.Domain)).ToCharArray(), 0, 254) }; packet.Length = packet.Data.Length; byte[] sendBuffer = DNSPacket.PacketToRaw(packet); try { Server.BeginSendTo(sendBuffer, 0, sendBuffer.Length, SocketFlags.None, endpoint, new AsyncCallback(ResponseCompleted), endpoint); return(true); } catch (Exception ex) { ErrorLog?.Invoke($"Error sending async response: '{ex.Message}'."); return(false); } }
public override PacketMainReturn interiorMain(ref Packet in_packet) { if (in_packet.Outbound && in_packet.ContainsLayer(Protocol.DNS)) { DNSPacket dns = (DNSPacket)in_packet; lock (cache) { DNSPacket.DNSAnswer[] answer; if (dns.Queries.Length > 0 && cache.TryGetValue(dns.Queries[0].ToString(), out answer)) { DNSPacket.DNSAnswer[] answers = answer; dns.Answers = answers; dns.DNSFlags = 0x8180; dns.UDPLength = (ushort)(8 + dns.LayerLength()); dns.TotalLength = (ushort)(20 + dns.UDPLength); dns.UDPChecksum = dns.GenerateUDPChecksum; dns.Outbound = false; IPAddress temp = dns.SourceIP; dns.SourceIP = dns.DestIP; dns.DestIP = temp; ushort t = dns.SourcePort; dns.SourcePort = dns.DestPort; dns.DestPort = t; dns.HeaderChecksum = dns.GenerateIPChecksum; dns.UDPChecksum = dns.GenerateUDPChecksum; return(new PacketMainReturn("DNSCache") { returnType = PacketMainReturnType.Edited }); } else { return(null); } } } else if (!in_packet.Outbound && in_packet.ContainsLayer(Protocol.DNS)) { lock (cache) { DNSPacket dns = (DNSPacket)in_packet; cache[dns.Queries[0].ToString()] = dns.Answers; } if (CacheUpdate != null) { new System.Threading.Thread(CacheUpdate).Start(); } return(null); } return(null); }
public void TestStubResolverAcceptsSeveralAliasesForAAAARecords() { // Make sure that chains of aliases are supported var relay = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 53); var expected_question = new DNSQuestion( new Domain("example.com"), ResourceRecordType.HOST_6ADDRESS, AddressClass.INTERNET); var expected_alias_answer_1 = new DNSRecord( new Domain("example.com"), AddressClass.INTERNET, 42, new CNAMEResource(new Domain("www.example.com"))); var expected_alias_answer_2 = new DNSRecord( new Domain("www.example.com"), AddressClass.INTERNET, 42, new CNAMEResource(new Domain("web1.www.example.com"))); var expected_addr_answer = new DNSRecord( new Domain("web1.www.example.com"), AddressClass.INTERNET, 42, new AAAAResource(IPv6Address.Parse("2001:cafe:beef::"))); var expected_packet = new DNSPacket( 42, false, QueryType.STANDARD_QUERY, false, false, true, true, ResponseType.NO_ERROR, new DNSQuestion[] { expected_question }, new DNSRecord[] { expected_alias_answer_1, expected_alias_answer_2, expected_addr_answer }, new DNSRecord[0], new DNSRecord[0]); Func <EndPoint, DNSQuestion, bool, DNSPacket> gives_direct_answers = (target, question, is_recursive) => { Assert.That(target, Is.EqualTo(relay)); Assert.That(question, Is.EqualTo(expected_question)); return(expected_packet); }; var resolver = new StubResolver(new NoopCache(), gives_direct_answers); var result = resolver.Resolve(new Domain("example.com"), ResourceRecordType.HOST_6ADDRESS, AddressClass.INTERNET, new EndPoint[] { relay }); var expected_result = new ResolverResult(); expected_result.answers = new DNSRecord[] { expected_addr_answer }; expected_result.aliases = new DNSRecord[] { expected_alias_answer_1, expected_alias_answer_2 }; expected_result.referrals = new DNSRecord[0]; expected_result.referral_additional = new DNSRecord[0]; Assert.That(result, Is.EqualTo(expected_result)); }
public void TestStubResolverAcceptsSOARecords() { // The same as the previous test, but this makes sure that less common // record types are still recognized as answers for the appropriate queries var relay = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 53); var expected_question = new DNSQuestion( new Domain("example.com"), ResourceRecordType.START_OF_AUTHORITY, AddressClass.INTERNET); var expected_answer = new DNSRecord( new Domain("example.com"), AddressClass.INTERNET, 42, new SOAResource( new Domain("ns.example.com"), new Domain("hostmaster.example.com"), 0, 360, 360, 360, 360)); var expected_packet = new DNSPacket( 42, false, QueryType.STANDARD_QUERY, false, false, true, true, ResponseType.NO_ERROR, new DNSQuestion[] { expected_question }, new DNSRecord[] { expected_answer }, new DNSRecord[0], new DNSRecord[0]); Func <EndPoint, DNSQuestion, bool, DNSPacket> gives_direct_answers = (target, question, is_recursive) => { Assert.That(target, Is.EqualTo(relay)); Assert.That(question, Is.EqualTo(expected_question)); return(expected_packet); }; var resolver = new StubResolver(new NoopCache(), gives_direct_answers); var result = resolver.Resolve(new Domain("example.com"), ResourceRecordType.START_OF_AUTHORITY, AddressClass.INTERNET, new EndPoint[] { relay }); var expected_result = new ResolverResult(); expected_result.answers = new DNSRecord[] { expected_answer }; expected_result.aliases = new DNSRecord[0]; expected_result.referrals = new DNSRecord[0]; expected_result.referral_additional = new DNSRecord[0]; Assert.That(result, Is.EqualTo(expected_result)); }
public void TestStubResolverReturnsRedirectionsWithAAAAResourceGlue() { // Make sure that any redirections are returned, even if there aren't any actual // results, along with their glue if provided var relay = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 53); var expected_question = new DNSQuestion( new Domain("example.com"), ResourceRecordType.HOST_ADDRESS, AddressClass.INTERNET); var expected_ns_answer = new DNSRecord( new Domain("example.com"), AddressClass.INTERNET, 42, new NSResource(new Domain("ns.example.com"))); var expected_glue_answer = new DNSRecord( new Domain("ns.example.com"), AddressClass.INTERNET, 42, new AAAAResource(IPv6Address.Parse("2001:cafe:beef::"))); var expected_packet = new DNSPacket( 42, false, QueryType.STANDARD_QUERY, false, false, true, true, ResponseType.NO_ERROR, new DNSQuestion[] { expected_question }, new DNSRecord[0], new DNSRecord[] { expected_ns_answer }, new DNSRecord[] { expected_glue_answer }); Func <EndPoint, DNSQuestion, bool, DNSPacket> gives_direct_answers = (target, question, is_recursive) => { Assert.That(target, Is.EqualTo(relay)); Assert.That(question, Is.EqualTo(expected_question)); return(expected_packet); }; var resolver = new StubResolver(new NoopCache(), gives_direct_answers); var result = resolver.Resolve(new Domain("example.com"), ResourceRecordType.HOST_ADDRESS, AddressClass.INTERNET, new EndPoint[] { relay }); var expected_result = new ResolverResult(); expected_result.answers = new DNSRecord[0]; expected_result.aliases = new DNSRecord[0]; expected_result.referrals = new DNSRecord[] { expected_ns_answer }; expected_result.referral_additional = new DNSRecord[] { expected_glue_answer }; Assert.That(result, Is.EqualTo(expected_result)); }
public void TestStubResolverSequenceOfRelays() { // Make sure that the resolver ignores failing resolvers, as long as at least one succeeds var good_relay = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 53); var bad_relay = new IPEndPoint(IPAddress.Parse("192.168.0.2"), 53); var expected_question = new DNSQuestion( new Domain("example.com"), ResourceRecordType.HOST_ADDRESS, AddressClass.INTERNET); var expected_answer = new DNSRecord( new Domain("example.com"), AddressClass.INTERNET, 42, new AResource(IPv4Address.Parse("192.168.0.1"))); var expected_packet = new DNSPacket( 42, false, QueryType.STANDARD_QUERY, false, false, true, true, ResponseType.NO_ERROR, new DNSQuestion[] { expected_question }, new DNSRecord[] { expected_answer }, new DNSRecord[0], new DNSRecord[0]); Func <EndPoint, DNSQuestion, bool, DNSPacket> gives_direct_answers = (target, question, is_recursive) => { if (target.Equals(bad_relay)) { throw new SocketException(); } Assert.That(target, Is.EqualTo(good_relay)); Assert.That(question, Is.EqualTo(expected_question)); return(expected_packet); }; var resolver = new StubResolver(new NoopCache(), gives_direct_answers); var result = resolver.Resolve(new Domain("example.com"), ResourceRecordType.HOST_ADDRESS, AddressClass.INTERNET, new EndPoint[] { bad_relay, good_relay }); var expected_result = new ResolverResult(); expected_result.answers = new DNSRecord[] { expected_answer }; expected_result.aliases = new DNSRecord[0]; expected_result.referrals = new DNSRecord[0]; expected_result.referral_additional = new DNSRecord[0]; Assert.That(result, Is.EqualTo(expected_result)); }
public void TestStubResolverRejectsIrrelevantGlue() { // Make sure that any redirections are returned, but rejects any bad glue var relay = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 53); var expected_question = new DNSQuestion( new Domain("example.com"), ResourceRecordType.HOST_ADDRESS, AddressClass.INTERNET); var expected_ns_answer = new DNSRecord( new Domain("example.com"), AddressClass.INTERNET, 42, new NSResource(new Domain("ns.example.com"))); var unexpected_glue_answer = new DNSRecord( new Domain("ns2.example.com"), AddressClass.INTERNET, 42, new AResource(IPv4Address.Parse("192.168.0.2"))); var expected_packet = new DNSPacket( 42, false, QueryType.STANDARD_QUERY, false, false, true, true, ResponseType.NO_ERROR, new DNSQuestion[] { expected_question }, new DNSRecord[0], new DNSRecord[] { expected_ns_answer }, new DNSRecord[] { unexpected_glue_answer }); Func <EndPoint, DNSQuestion, bool, DNSPacket> gives_direct_answers = (target, question, is_recursive) => { Assert.That(target, Is.EqualTo(relay)); Assert.That(question, Is.EqualTo(expected_question)); return(expected_packet); }; var resolver = new StubResolver(new NoopCache(), gives_direct_answers); var result = resolver.Resolve(new Domain("example.com"), ResourceRecordType.HOST_ADDRESS, AddressClass.INTERNET, new EndPoint[] { relay }); var expected_result = new ResolverResult(); expected_result.answers = new DNSRecord[0]; expected_result.aliases = new DNSRecord[0]; expected_result.referrals = new DNSRecord[] { expected_ns_answer }; expected_result.referral_additional = new DNSRecord[0]; Assert.That(result, Is.EqualTo(expected_result)); }
public void TestStubResolverAcceptsARecords() { // The idea behind this test is to make sure that direct answers to the question are accpted // (no CNAMEs, no referrals, etc.). A records are the most common query, so they are a good // starting point. var relay = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 53); var expected_question = new DNSQuestion( new Domain("example.com"), ResourceRecordType.HOST_ADDRESS, AddressClass.INTERNET); var expected_answer = new DNSRecord( new Domain("example.com"), AddressClass.INTERNET, 42, new AResource(IPv4Address.Parse("192.168.0.1"))); var expected_packet = new DNSPacket( 42, false, QueryType.STANDARD_QUERY, false, false, true, true, ResponseType.NO_ERROR, new DNSQuestion[] { expected_question }, new DNSRecord[] { expected_answer }, new DNSRecord[0], new DNSRecord[0]); Func <EndPoint, DNSQuestion, bool, DNSPacket> gives_direct_answers = (target, question, is_recursive) => { Assert.That(target, Is.EqualTo(relay)); Assert.That(question, Is.EqualTo(expected_question)); return(expected_packet); }; var resolver = new StubResolver(new NoopCache(), gives_direct_answers); var result = resolver.Resolve(new Domain("example.com"), ResourceRecordType.HOST_ADDRESS, AddressClass.INTERNET, new EndPoint[] { relay }); var expected_result = new ResolverResult(); expected_result.answers = new DNSRecord[] { expected_answer }; expected_result.aliases = new DNSRecord[0]; expected_result.referrals = new DNSRecord[0]; expected_result.referral_additional = new DNSRecord[0]; Assert.That(result, Is.EqualTo(expected_result)); }
/// <summary> /// Connects with the provided DNS Server and retrieves the DNS name by looking up the given IP. /// </summary> /// <param name="ipadd">the ip address you want a DNS name for.</param> /// <returns></returns> public string RetrieveDNSName(string ipadd) { Connect(); DNSPacket packet = new DNSPacket { Type = DNSPacket.PacketType.Request, Lookup = DNSPacket.LookupType.ARPA, Data = Encoding.ASCII.GetBytes(ipadd) }; packet.Length = packet.Data.Length; byte[] raw = DNSPacket.PacketToRaw(packet); Client.Send(raw, packet.Length + 3); IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(Address), 51); byte[] answer = Client.Receive(ref ipep); string responseData; if (answer.Length != 0 && ipep.Address.ToString().Equals(Address)) { //checks if the response came from the DNS server DNSPacket response = DNSPacket.RawToPacket(answer); if (response.Type == DNSPacket.PacketType.Response && response.Lookup == DNSPacket.LookupType.ARPA) { responseData = Encoding.ASCII.GetString(response.Data, 0, response.Length); } else { throw new DNSException(response, "Expected a Response and Name type, got something else."); } } else { throw new DNSException(null, "Received empty response or the response came from the wrong host."); } Disconnect(); return(responseData); }
public void TestStubResolverRecordsCNAMEAnswers() { // This ensures that any request for a CNAME to a paritcular domain ends up in the answers // list (and only the answers list) if we're asking for CNAMEs var relay = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 53); var expected_question = new DNSQuestion( new Domain("example.com"), ResourceRecordType.CANONICAL_NAME, AddressClass.INTERNET); var expected_answer = new DNSRecord( new Domain("example.com"), AddressClass.INTERNET, 42, new CNAMEResource(new Domain("www.example.com"))); var expected_packet = new DNSPacket( 42, false, QueryType.STANDARD_QUERY, false, false, true, true, ResponseType.NO_ERROR, new DNSQuestion[] { expected_question }, new DNSRecord[] { expected_answer }, new DNSRecord[0], new DNSRecord[0]); Func <EndPoint, DNSQuestion, bool, DNSPacket> gives_direct_answers = (target, question, is_recursive) => { Assert.That(target, Is.EqualTo(relay)); Assert.That(question, Is.EqualTo(expected_question)); return(expected_packet); }; var resolver = new StubResolver(new NoopCache(), gives_direct_answers); var result = resolver.Resolve(new Domain("example.com"), ResourceRecordType.CANONICAL_NAME, AddressClass.INTERNET, new EndPoint[] { relay }); var expected_result = new ResolverResult(); expected_result.answers = new DNSRecord[] { expected_answer }; expected_result.aliases = new DNSRecord[0]; expected_result.referrals = new DNSRecord[0]; expected_result.referral_additional = new DNSRecord[0]; Assert.That(result, Is.EqualTo(expected_result)); }
internal static void ProcessDNSRequest(byte[] data, string clientIP, int clientPort, string sourceIP, int sourcePort) { DNSPacket packet = new DNSPacket(data) { Host = Program.argDNSHost, TTL = uint.Parse(Program.argDNSTTL) }; DNSListener listener = new DNSListener(UInt32.Parse(Program.argDNSTTL)); if (!packet.Header.IsDynamicUpdateRequest()) { if (packet.Header.IsQuery()) { if (listener.Check(packet.Question.Name, packet.Question.Type, clientIP, out string message)) { byte[] buffer = packet.GetBytes(UInt32.Parse(Program.argDNSTTL), Program.dnsSerial, Program.argSpooferIP, Program.argSpooferIPv6); if (!Utilities.ArrayIsNullOrEmpty(buffer)) { UDPSocket.SendTo(clientIP, clientPort, sourceIP, sourcePort, buffer, false); } } Output.SpooferOutput("DNS", packet.Question.Type, packet.Question.Name, clientIP, message); } } else { byte[] flags = new byte[2] { 0xa8, 0x05 }; byte[] dnsPayload = new byte[data.Length - 2]; System.Buffer.BlockCopy(data, 2, dnsPayload, 0, dnsPayload.Length); MemoryStream dnsMemoryStream = new MemoryStream(); dnsMemoryStream.Write(data, 0, data.Length); dnsMemoryStream.Position = 2; dnsMemoryStream.Write(flags, 0, 2); UDPSocket.SendTo(clientIP, clientPort, sourceIP, sourcePort, dnsMemoryStream.ToArray(), false); } }
/** * Sends a DNS query to the given server, and waits for a response. * Possibly times out with a SocketException if the response takes * too long. */ public static DNSPacket SendQuery(EndPoint server, DNSQuestion question, bool recursive) { var rng = new Random(); var packet_id = (UInt16)rng.Next(0, (1 << 16) - 1); var to_send = new DNSPacket( packet_id, true, QueryType.STANDARD_QUERY, false, false, recursive, false, ResponseType.NO_ERROR, new DNSQuestion[] { question }, new DNSRecord[0], new DNSRecord[0], new DNSRecord[0]); var send_bytes = to_send.ToBytes(); using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { socket.ReceiveTimeout = 5 * 1000; socket.Bind(new IPEndPoint(IPAddress.Any, 0)); logger.Trace("Sending packet {0} to {1}", packet_id, server); socket.SendTo(send_bytes, server); DNSPacket recv_packet = null; while (recv_packet == null) { logger.Trace("Preparing to receive"); var recv_bytes = new byte[512]; EndPoint remote_endpoint = new IPEndPoint(IPAddress.Any, 0); socket.ReceiveFrom(recv_bytes, ref remote_endpoint); recv_packet = DNSPacket.FromBytes(recv_bytes); if (recv_packet.Id != packet_id) { logger.Trace("Trashing bad packet"); recv_packet = null; } } logger.Trace("Got response {0}", recv_packet); return(recv_packet); } }
protected virtual void ProcessRequest(byte[] data, UDPListener udpListener, IPEndPoint ipEndPoint, string replyIP, string replyIPv6) { string clientIP = ipEndPoint.Address.ToString(); DNSPacket packet = new DNSPacket(data) { Host = this.Host, TTL = this.TTL }; if (packet.Header.IsQuery()) { if (!packet.Header.IsDynamicUpdateRequest()) { if (Check(packet.Question.Name, packet.Question.Type, clientIP, out string message)) { byte[] buffer; buffer = packet.GetBytes(this.TTL, this.Serial, replyIP, replyIPv6); SendTo(buffer, udpListener, ipEndPoint); } Output("DNS", clientIP, packet.Question.Name, packet.Question.Type, message); } else { byte[] flags = new byte[2] { 0xa8, 0x05 }; byte[] dnsPayload = new byte[data.Length - 2]; System.Buffer.BlockCopy(data, 2, dnsPayload, 0, dnsPayload.Length); MemoryStream dnsMemoryStream = new MemoryStream(); dnsMemoryStream.Write(data, 0, data.Length); dnsMemoryStream.Position = 2; dnsMemoryStream.Write(flags, 0, 2); SendTo(dnsMemoryStream.ToArray(), udpListener, ipEndPoint); } } }
/// <summary> /// /// </summary> /// <param name="root"></param> /// <param name="logger"></param> /// <returns></returns> public byte[] ToArray(DataKey root, Logger logger) { return(DNSPacket.FromDataKey(root).ToArray()); }
protected override void Run() { /** * Packet creation and parsing tests **/ /** Ethernet Packet Parsing Test **/ byte[] ethernetPacketData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0C, 0x29, 0xD5, 0xDB, 0x9D, 0x08, 0x00 }; EthernetPacket ethernetPacket = new EthernetPacket(ethernetPacketData); Equals(ethernetPacketData, ethernetPacket.RawData); /** IP Packet Parsing Test **/ byte[] ipPacketData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0C, 0x29, 0xD5, 0xDB, 0x9D, 0x08, 0x00, 0x45, 0x00, 0x01, 0x16, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x39, 0xD8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }; IPPacket ipPacket = new IPPacket(ipPacketData); Equals(ipPacketData, ipPacket.RawData); /** UDP Packet Parsing Test **/ byte[] udpPacketData = new byte[] { 0x98, 0xFA, 0x9B, 0xD4, 0xEB, 0x29, 0xD8, 0xCE, 0x3A, 0x89, 0x3E, 0xD9, 0x08, 0x00, 0x45, 0x00, 0x00, 0x22, 0x0C, 0x74, 0x40, 0x00, 0x40, 0x11, 0xAA, 0xBE, 0xC0, 0xA8, 0x01, 0x02, 0xC0, 0xA8, 0x01, 0x46, 0x10, 0x92, 0x10, 0x92, 0x00, 0x0E, 0x37, 0x22, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x21 }; UDPPacket udpPacket = new UDPPacket(udpPacketData); Equals(udpPacketData, udpPacket.RawData); /** DNS Packet Parsing Test **/ byte[] dnsPacketData = new byte[] { 0xB8, 0xD9, 0x4D, 0xC1, 0xA5, 0xFC, 0x98, 0xFA, 0x9B, 0xD4, 0xEB, 0x29, 0x08, 0x00, 0x45, 0x00, 0x00, 0x38, 0xC3, 0x1C, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0xC0, 0xA8, 0x01, 0x46, 0xC0, 0xA8, 0x01, 0xFE, 0xF0, 0x66, 0x00, 0x35, 0x00, 0x24, 0x84, 0xCA, 0xD6, 0x80, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x69, 0x74, 0x74, 0x65, 0x72, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01 }; DNSPacket dnsPacket = new DNSPacket(dnsPacketData); Equals(dnsPacketData, dnsPacket.RawData); /** DHCP Packet Parsing Test **/ byte[] dhcpPacketData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0xD9, 0x4D, 0xC1, 0xA5, 0xFC, 0x08, 0x00, 0x45, 0xC0, 0x01, 0x59, 0x46, 0x3F, 0x00, 0x00, 0x40, 0x11, 0x6F, 0xEF, 0xC0, 0xA8, 0x01, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x43, 0x00, 0x44, 0x01, 0x45, 0xD3, 0xC8, 0x02, 0x01, 0x06, 0x00, 0x84, 0xA9, 0x5A, 0x66, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, 0x01, 0x47, 0xC0, 0xA8, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE1, 0x2D, 0xA3, 0x06, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0xC0, 0xA8, 0x01, 0xFE, 0x33, 0x04, 0x00, 0x01, 0x51, 0x80, 0x3A, 0x04, 0x00, 0x00, 0xA8, 0xC0, 0x3B, 0x04, 0x00, 0x01, 0x27, 0x50, 0x1C, 0x04, 0xC0, 0xA8, 0x01, 0xFF, 0x51, 0x12, 0x03, 0xFF, 0xFF, 0x44, 0x45, 0x53, 0x4B, 0x54, 0x4F, 0x50, 0x2D, 0x49, 0x51, 0x48, 0x4A, 0x33, 0x31, 0x43, 0x06, 0x04, 0xC0, 0xA8, 0x01, 0xFE, 0x0F, 0x03, 0x6C, 0x61, 0x6E, 0x03, 0x04, 0xC0, 0xA8, 0x01, 0xFE, 0x01, 0x04, 0xFF, 0xFF, 0xFF, 0x00, 0xFF }; DHCPPacket dhcpPacket = new DHCPPacket(dhcpPacketData); Equals(dhcpPacketData, dhcpPacket.RawData); /** ARP Packet Parsing Test **/ byte[] arpPacketData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0xD9, 0x4D, 0xC1, 0xA5, 0xFC, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xB8, 0xD9, 0x4D, 0xC1, 0xA5, 0xFC, 0xC0, 0xA8, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, 0x01, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ARPPacket arpPacket = new ARPPacket(arpPacketData); Equals(arpPacketData, arpPacket.RawData); TestController.Completed(); /** * Clients tests **/ var dhcpCLient = new DHCPClient(); dhcpCLient.Close(); var dnsClient = new DnsClient(); dnsClient.Close(); var udpClient = new UdpClient(); udpClient.Close(); var icmpClient = new ICMPClient(); icmpClient.Close(); }
private void RespondToClient(byte[] buffer, EndPoint peer) { UInt16 outbound_id; var outbound_is_authority = false; QueryType outbound_qtype; bool outbound_recursive_request; bool outbound_recursive_response = false; ResponseType outbound_rtype; var outbound_questions = new List <DNSQuestion>(); var outbound_answers = new List <DNSRecord>(); var outbound_authoritative = new List <DNSRecord>(); var outbound_additional = new List <DNSRecord>(); try { var inbound = DNSPacket.FromBytes(buffer); outbound_id = inbound.Id; outbound_qtype = inbound.QueryType; outbound_recursive_request = inbound.RecursiveRequest; logger.Trace("{0}: Parsed inbound request {1}", peer, inbound); outbound_questions.AddRange(inbound.Questions); if (inbound.QueryType == QueryType.UNSUPPORTED) { logger.Trace("{0}: Unsupported query type", peer); outbound_rtype = ResponseType.NOT_IMPLEMENTED; } else if (inbound.Questions.Length != 1) { // BIND does this, so apparently we're in good company if we turn down multi-question packets logger.Trace("{0}: Multi-question packet", peer); outbound_rtype = ResponseType.NOT_IMPLEMENTED; } else { outbound_recursive_response = outbound_recursive_request; var question = inbound.Questions[0]; // We *could* find a way to communicate the rejection of a // single question, but it's simpler to just reject the // whole thing if (question.QueryType == ResourceRecordType.UNSUPPORTED || question.AddressClass == AddressClass.UNSUPPORTED) { logger.Trace("{0}: Unsupported question {1}", peer, question); outbound_rtype = ResponseType.NOT_IMPLEMENTED; } else { try { var answer = query_exec.Execute(question.Name, question.QueryType, question.AddressClass, inbound.RecursiveRequest); if (answer.FoundAnswer) { logger.Trace("{0}: Resolver found answer for {1}", peer, question); outbound_rtype = ResponseType.NO_ERROR; outbound_is_authority = answer.IsAuthority; outbound_answers.AddRange(answer.Answers); outbound_additional.AddRange(answer.Additional); outbound_authoritative.AddRange(answer.Authority); } else { logger.Trace("{0}: Could not find the name {1}", peer, question.Name); outbound_rtype = ResponseType.NAME_ERROR; outbound_is_authority = answer.IsAuthority; } } catch (Exception err) { Console.WriteLine(err); logger.Error(err, "{0}: Server failure", peer); outbound_rtype = ResponseType.SERVER_FAILURE; outbound_is_authority = false; } } } } catch (InvalidDataException err) { // If this is the case, we have to at least extract the ID so // that the peer knows what we're complaining about logger.Trace("{0}: Unparsable request ({1})", peer, err.Message); var in_id = (UInt16)((buffer[0] << 8) + buffer[1]); outbound_id = in_id; outbound_qtype = QueryType.STANDARD_QUERY; outbound_is_authority = false; outbound_recursive_request = false; outbound_recursive_response = false; outbound_rtype = ResponseType.FORMAT_ERROR; } var outbound = new DNSPacket( outbound_id, false, outbound_qtype, outbound_is_authority, false, outbound_recursive_request, outbound_recursive_response, outbound_rtype, outbound_questions, outbound_answers, outbound_authoritative, outbound_additional); var outbound_bytes = outbound.ToBytes(); logger.Trace("{0}: Sending {1}-byte response {2}", peer, outbound_bytes.Length, outbound); server.SendTo(outbound_bytes, peer); }
/// <summary> /// /// </summary> /// <param name="data"></param> /// <param name="root"></param> /// <param name="logger"></param> public void FromArray(byte[] data, DataKey root, Logger logger) { DNSPacket packet = DNSPacket.FromArray(data); packet.ToDataKey(root); }
public override void Run(IDataAdapter adapter, Logger logger) { DataFrame frame = adapter.Read(); while (frame != null) { try { DNSPacket packet = DNSPacket.FromArray(frame.ToArray()); List <DNSPacket.DNSRRBase> aRecords = new List <DNSPacket.DNSRRBase>(); foreach (DNSPacket.DNSQuestion question in packet.Questions) { if ((question.QClass == DNSPacket.DNSClass.IN) || (question.QClass == DNSPacket.DNSClass.AnyClass)) { if ((question.QType == DNSPacket.DNSType.A) || (question.QType == DNSPacket.DNSType.AllRecords)) { if (Config.ResponseAddress != IPAddress.Any) { DNSPacket.ADNSRR addr = new DNSPacket.ADNSRR(); addr.Address = new IPAddress(Config.ResponseAddress.GetAddressBytes()); addr.TimeToLive = Config.TimeToLive; addr.Type = DNSPacket.DNSType.A; addr.Class = DNSPacket.DNSClass.IN; addr.Name = question.QName; aRecords.Add(addr); } } if ((question.QType == DNSPacket.DNSType.AAAA) || (question.QType == DNSPacket.DNSType.AllRecords)) { if (Config.ResponseAddress6 != IPAddress.IPv6Any) { DNSPacket.AAAADNSRR addr = new DNSPacket.AAAADNSRR(); addr.Address = new IPAddress(Config.ResponseAddress6.GetAddressBytes()); addr.TimeToLive = Config.TimeToLive; addr.Type = DNSPacket.DNSType.AAAA; addr.Class = DNSPacket.DNSClass.IN; addr.Name = question.QName; aRecords.Add(addr); } } if ((question.QType == DNSPacket.DNSType.PTR) || (question.QType == DNSPacket.DNSType.AllRecords)) { if (!String.IsNullOrEmpty(Config.ReverseDns) && ((question.QName.EndsWith(".in-addr.arpa.") || question.QName.EndsWith(".ip6.arpa.")))) { DNSPacket.PTRDNSRR addr = new DNSPacket.PTRDNSRR(); addr.Ptr = Config.ReverseDns; addr.Type = DNSPacket.DNSType.PTR; addr.Class = DNSPacket.DNSClass.IN; addr.Name = question.QName; aRecords.Add(addr); } } } } packet.Query = true; packet.RecursionAvailable = true; if (aRecords.Count > 0) { packet.Answers = aRecords.ToArray(); packet.AuthoritiveAnswer = true; packet.ResponseCode = DNSPacket.DNSRCode.NoError; } else { packet.ResponseCode = DNSPacket.DNSRCode.Refused; } adapter.Write(new DataFrame(packet.ToArray())); } catch (ArgumentException ex) { logger.LogException(ex); } frame = adapter.Read(); } }
protected override void Run() { /** * Packet creation and parsing tests **/ /** Ethernet Packet Parsing Test **/ byte[] ethernetPacketData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0C, 0x29, 0xD5, 0xDB, 0x9D, 0x08, 0x00 }; EthernetPacket ethernetPacket = new EthernetPacket(ethernetPacketData); Equals(ethernetPacketData, ethernetPacket.RawData); /** IP Packet Parsing Test **/ byte[] ipPacketData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x0C, 0x29, 0xD5, 0xDB, 0x9D, 0x08, 0x00, 0x45, 0x00, 0x01, 0x16, 0x00, 0x00, 0x00, 0x00, 0x80, 0x11, 0x39, 0xD8, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF }; IPPacket ipPacket = new IPPacket(ipPacketData); Equals(ipPacketData, ipPacket.RawData); /** UDP Packet Parsing Test **/ byte[] udpPacketData = new byte[] { 0x98, 0xFA, 0x9B, 0xD4, 0xEB, 0x29, 0xD8, 0xCE, 0x3A, 0x89, 0x3E, 0xD9, 0x08, 0x00, 0x45, 0x00, 0x00, 0x22, 0x0C, 0x74, 0x40, 0x00, 0x40, 0x11, 0xAA, 0xBE, 0xC0, 0xA8, 0x01, 0x02, 0xC0, 0xA8, 0x01, 0x46, 0x10, 0x92, 0x10, 0x92, 0x00, 0x0E, 0x37, 0x22, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x21 }; UDPPacket udpPacket = new UDPPacket(udpPacketData); Equals(udpPacketData, udpPacket.RawData); /** DNS Packet Parsing Test **/ byte[] dnsPacketData = new byte[] { 0xB8, 0xD9, 0x4D, 0xC1, 0xA5, 0xFC, 0x98, 0xFA, 0x9B, 0xD4, 0xEB, 0x29, 0x08, 0x00, 0x45, 0x00, 0x00, 0x38, 0xC3, 0x1C, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0xC0, 0xA8, 0x01, 0x46, 0xC0, 0xA8, 0x01, 0xFE, 0xF0, 0x66, 0x00, 0x35, 0x00, 0x24, 0x84, 0xCA, 0xD6, 0x80, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x69, 0x74, 0x74, 0x65, 0x72, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x00, 0x01, 0x00, 0x01 }; DNSPacket dnsPacket = new DNSPacket(dnsPacketData); Equals(dnsPacketData, dnsPacket.RawData); /** DHCP Packet Parsing Test **/ byte[] dhcpPacketData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0xD9, 0x4D, 0xC1, 0xA5, 0xFC, 0x08, 0x00, 0x45, 0xC0, 0x01, 0x59, 0x46, 0x3F, 0x00, 0x00, 0x40, 0x11, 0x6F, 0xEF, 0xC0, 0xA8, 0x01, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x43, 0x00, 0x44, 0x01, 0x45, 0xD3, 0xC8, 0x02, 0x01, 0x06, 0x00, 0x84, 0xA9, 0x5A, 0x66, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, 0x01, 0x47, 0xC0, 0xA8, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE1, 0x2D, 0xA3, 0x06, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x82, 0x53, 0x63, 0x35, 0x01, 0x05, 0x36, 0x04, 0xC0, 0xA8, 0x01, 0xFE, 0x33, 0x04, 0x00, 0x01, 0x51, 0x80, 0x3A, 0x04, 0x00, 0x00, 0xA8, 0xC0, 0x3B, 0x04, 0x00, 0x01, 0x27, 0x50, 0x1C, 0x04, 0xC0, 0xA8, 0x01, 0xFF, 0x51, 0x12, 0x03, 0xFF, 0xFF, 0x44, 0x45, 0x53, 0x4B, 0x54, 0x4F, 0x50, 0x2D, 0x49, 0x51, 0x48, 0x4A, 0x33, 0x31, 0x43, 0x06, 0x04, 0xC0, 0xA8, 0x01, 0xFE, 0x0F, 0x03, 0x6C, 0x61, 0x6E, 0x03, 0x04, 0xC0, 0xA8, 0x01, 0xFE, 0x01, 0x04, 0xFF, 0xFF, 0xFF, 0x00, 0xFF }; DHCPPacket dhcpPacket = new DHCPPacket(dhcpPacketData); Equals(dhcpPacketData, dhcpPacket.RawData); /** TCP Packet Parsing Test **/ byte[] tcpPacketData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x00, 0x45, 0x00, 0x00, 0x3C, 0x64, 0x92, 0x40, 0x00, 0x40, 0x06, 0x51, 0xA2, 0xC0, 0xA8, 0x01, 0xD3, 0xC0, 0xA8, 0x01, 0x64, 0xA8, 0xAB, 0x10, 0x92, 0x67, 0x7C, 0xCE, 0x18, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x02, 0x72, 0x10, 0x5F, 0xF0, 0x00, 0x00, 0x02, 0x04, 0x05, 0xB4, 0x04, 0x02, 0x08, 0x0A, 0x58, 0x1A, 0xAA, 0x8A, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x07 }; TCPPacket tcpPacket = new TCPPacket(tcpPacketData); Equals(tcpPacket.SourcePort, 43179); Equals(tcpPacket.DestinationPort, 4242); Equals(tcpPacket.SequenceNumber, 0x677CCE18); Equals(tcpPacket.AckNumber, 0); Equals(tcpPacket.TCPFlags, Flags.SYN); Equals(tcpPacket.WindowSize, 29200); Equals(tcpPacket.Checksum, 0x5FF0); Equals(tcpPacket.UrgentPointer, 0); /** ARP Packet Parsing Test **/ byte[] arpPacketData = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0xD9, 0x4D, 0xC1, 0xA5, 0xFC, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xB8, 0xD9, 0x4D, 0xC1, 0xA5, 0xFC, 0xC0, 0xA8, 0x01, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xA8, 0x01, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ARPPacket arpPacket = new ARPPacket(arpPacketData); Equals(arpPacketData, arpPacket.RawData); TestController.Completed(); /** * Clients tests **/ var dhcpCLient = new DHCPClient(); dhcpCLient.Close(); var dnsClient = new DnsClient(); dnsClient.Close(); var udpClient = new UdpClient(); udpClient.Close(); var tcpClient = new TcpClient(4242); tcpClient.Close(); var icmpClient = new ICMPClient(); icmpClient.Close(); }