Пример #1
0
        public byte[] Build(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
        {
            // Combind the NsFlags with our constant flags
            const ushort flags = (ushort)((ushort)QueryResponse.Query | (ushort)OpCode.QUERY | (ushort)NsFlags.RD);

            var bDnsQuery = GetMessageBytes(
                (ushort)_random.Next(),
                flags,
                1,
                0,
                0,
                host,
                queryType,
                queryClass);

            // Add two byte prefix that contains the packet length per RFC 1035 section 4.2.2
            if (protocol == ProtocolType.Tcp)
            {
                // 4.2.2. TCP usageMessages sent over TCP connections use server port 53 (decimal).
                // The message is prefixed with a two byte length field which gives the message
                // length, excluding the two byte length field.  This length field allows the
                // low-level processing to assemble a complete message before beginning to parse
                // it.
                var len = bDnsQuery.Length;
                Array.Resize <byte>(ref bDnsQuery, len + 2);
                Array.Copy(bDnsQuery, 0, bDnsQuery, 2, len);
                bDnsQuery[0] = (byte)((len >> 8) & 0xFF);
                bDnsQuery[1] = (byte)((len & 0xFF));
            }

            return(bDnsQuery);
        }
Пример #2
0
        public DnsQueryResponse Resolve(string host, NsType queryType, NsClass queryClass, ProtocolType protocol, TsigMessageSecurityProvider provider)
        {
            string dnsServer = string.Empty;

            // Test for Unix/Linux OS
            if (Tools.IsPlatformLinuxUnix())
            {
                dnsServer = Tools.DiscoverUnixDnsServerAddress();
            }
            else
            {
                IPAddressCollection dnsServerCollection = Tools.DiscoverDnsServerAddresses();
                if (dnsServerCollection.Count == 0)
                {
                    throw new Exception("Couldn't detect local DNS Server.");
                }

                dnsServer = dnsServerCollection[0].ToString();
            }

            if (String.IsNullOrEmpty(dnsServer))
            {
                throw new Exception("Couldn't detect local DNS Server.");
            }

            return(Resolve(dnsServer, host, queryType, queryClass, protocol, provider));
        }
        public byte[] Build(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
        {
            // Combind the NsFlags with our constant flags
            const ushort flags = (ushort)((ushort)QueryResponse.Query | (ushort)OpCode.QUERY | (ushort)NsFlags.RD);

            var bDnsQuery = GetMessageBytes(
                (ushort)_random.Next(),
                flags,
                1,
                0,
                0,
                host,
                queryType,
                queryClass);

            // Add two byte prefix that contains the packet length per RFC 1035 section 4.2.2
            if (protocol == ProtocolType.Tcp)
            {
                // 4.2.2. TCP usageMessages sent over TCP connections use server port 53 (decimal).  
                // The message is prefixed with a two byte length field which gives the message 
                // length, excluding the two byte length field.  This length field allows the 
                // low-level processing to assemble a complete message before beginning to parse 
                // it.
                var len = bDnsQuery.Length;
                Array.Resize<byte>(ref bDnsQuery, len + 2);
                Array.Copy(bDnsQuery, 0, bDnsQuery, 2, len);
                bDnsQuery[0] = (byte)((len >> 8) & 0xFF);
                bDnsQuery[1] = (byte)((len & 0xFF));
            }

            return bDnsQuery;
        }
Пример #4
0
 /// <summary>
 /// Initalise the <see cref="RecordHeader"/>
 /// </summary>
 /// <param name="name">The header name</param>
 /// <param name="nsType">The resource type</param>
 /// <param name="nsClass">The class type</param>
 /// <param name="timeToLive">The time to live</param>
 public RecordHeader(string name, NsType nsType, NsClass nsClass, int timeToLive)
 {
     _name       = name;
     _nsType     = nsType;
     _nsClass    = nsClass;
     _timeToLive = timeToLive;
 }
Пример #5
0
        // NOTE: the order of class & type w/libresolv are the opposite of this DnDns package!
        public static int SystemResQuery(string host, NsClass dnsClass, NsType dnsType, byte[] answer)
        {
#if __IOS__
            return(res_query(host, (int)dnsClass, (int)dnsType, answer, answer.Length));
#else
            return(-1);
#endif
        }
Пример #6
0
 public Task <DnsQueryResponse> ResolveAsync(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
 {
     return(Task.Factory.StartNew <DnsQueryResponse> (() => {
         try {
             return Resolve(host, queryType, queryClass, protocol);
         } catch {
             // FIXME - uplevel this code to work with cancellation token.
             return null;
         }
     }));
 }
Пример #7
0
 public DnsQueryResponse Resolve(string host, NsType queryType, NsClass queryClass, ProtocolType protocol, TsigMessageSecurityProvider provider)
 {
     foreach (var server in GetDnsServers())
     {
         try {
             return(Resolve(server, host, queryType, queryClass, protocol, provider));
         } catch (Exception ex) {
             Console.WriteLine(string.Format("DnsQueryRequest.Resolve: Could not resolve host {0}: {1}", host, ex));
         }
     }
     return(null);
 }
Пример #8
0
 /// <summary>
 /// Initalise the <see cref="RecordHeaderParser"/>
 /// </summary>
 /// <param name="name">The header name</param>
 /// <param name="nsType">The resource type</param>
 /// <param name="nsClass">The class type</param>
 /// <param name="timeToLive">The time to live</param>
 /// /// <param name="dataLength">Length of header data</param>
 public RecordHeader(
     string name,
     NsType nsType,
     NsClass nsClass,
     int timeToLive,
     short dataLength)
 {
     _name       = name;
     _nsType     = nsType;
     _nsClass    = nsClass;
     _timeToLive = timeToLive;
     _dataLength = dataLength;
 }
Пример #9
0
 /// <summary>
 /// Initalise the <see cref="RecordHeaderParser"/>
 /// </summary>
 /// <param name="name">The header name</param>
 /// <param name="nsType">The resource type</param>
 /// <param name="nsClass">The class type</param>
 /// <param name="timeToLive">The time to live</param>
 /// /// <param name="dataLength">Length of header data</param>
 public RecordHeader(
     string name, 
     NsType nsType, 
     NsClass nsClass, 
     int timeToLive,
     short dataLength)
 {
     _name = name;
     _nsType = nsType;
     _nsClass = nsClass;
     _timeToLive = timeToLive;
     _dataLength = dataLength;
 }
Пример #10
0
 protected Message(
     ushort transactionId,
     ushort flags,
     QueryResponse queryResponse,
     OpCode opCode, NsFlags nsFlags,
     RCode rCode, ushort questions,
     ushort answerRRs,
     ushort authorityRRs,
     string name,
     NsType nsType,
     NsClass nsClass,
     List <Record> additionalRecords)
 {
 }
Пример #11
0
        protected Message(
            ushort transactionId, 
            ushort flags, 
            QueryResponse queryResponse, 
            OpCode opCode, NsFlags nsFlags, 
            RCode rCode, ushort questions, 
            ushort answerRRs, 
            ushort authorityRRs, 
            string name, 
            NsType nsType, 
            NsClass nsClass,
            List<Record> additionalRecords)
        {

        }
Пример #12
0
        byte[] GetMessageBytes(
            ushort transactionId,
            ushort flags,
            ushort questions,
            ushort answerRRs,
            ushort authorityRRs,
            string name,
            NsType nsType,
            NsClass nsClass
            )
        {
            var memoryStream = new MemoryStream();
            var data         = new byte[2];

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(transactionId) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(flags) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(questions) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(answerRRs) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(authorityRRs) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(0) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = CanonicaliseDnsName(name, false);
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)nsType) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)nsClass) >> 16));
            memoryStream.Write(data, 0, data.Length);

            _logger.Trace("The message bytes: {0}", DumpArrayToString(memoryStream.ToArray()));

            return(memoryStream.ToArray());
        }
Пример #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="dnsServer"></param>
        /// <param name="host"></param>
        /// <param name="queryType"></param>
        /// <param name="queryClass"></param>
        /// <param name="protocol"></param>
        /// <param name="messageSecurityProvider">The instance of the message security provider to use to secure the DNS request.</param>
        /// <returns>A <see cref="T:DnDns.Net.Dns.DnsQueryResponse"></see> instance that contains the Dns Answer for the request query.</returns>
        /// <PermissionSet>
        ///     <IPermission class="System.Net.DnsPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
        /// </PermissionSet>
        public DnsQueryResponse Resolve(string dnsServer, string host, NsType queryType, NsClass queryClass, ProtocolType protocol, IMessageSecurityProvider messageSecurityProvider)
        {
            // Do stack walk and Demand all callers have DnsPermission.
            _dnsPermissions.Demand();

            byte[] bDnsQuery = this.BuildDnsRequest(host, queryType, queryClass, protocol, messageSecurityProvider);

            // Connect to DNS server and get the record for the current server.
            IPHostEntry ipe  = System.Net.Dns.GetHostEntry(dnsServer);
            IPAddress   ipa  = ipe.AddressList[0];
            IPEndPoint  ipep = new IPEndPoint(ipa, (int)UdpServices.Domain);

            byte[] recvBytes = null;

            switch (protocol)
            {
            case ProtocolType.Tcp:
            {
                recvBytes = ResolveTcp(bDnsQuery, ipep);
                break;
            }

            case ProtocolType.Udp:
            {
                recvBytes = ResolveUdp(bDnsQuery, ipep);
                break;
            }

            default:
            {
                throw new InvalidOperationException("Invalid Protocol: " + protocol);
            }
            }

            Trace.Assert(recvBytes != null, "Failed to retrieve data from the remote DNS server.");

            DnsQueryResponse dnsQR = new DnsQueryResponse();

            dnsQR.ParseResponse(recvBytes, protocol);

            return(dnsQR);
        }
Пример #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="dnsServer"></param>
        /// <param name="host"></param>
        /// <param name="queryType"></param>
        /// <param name="queryClass"></param>
        /// <param name="protocol"></param>
        /// <param name="messageSecurityProvider">The instance of the message security provider to use to secure the DNS request.</param>
        /// <returns>A <see cref="T:DnDns.Net.Dns.DnsQueryResponse"></see> instance that contains the Dns Answer for the request query.</returns>
        /// <PermissionSet>
        ///     <IPermission class="System.Net.DnsPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
        /// </PermissionSet>
        public async Task <DnsQueryResponse> Resolve(string dnsServer, string host, NsType queryType, NsClass queryClass, ProtocolType protocol, IMessageSecurityProvider messageSecurityProvider)
        {
            byte[] bDnsQuery = this.BuildDnsRequest(host, queryType, queryClass, protocol, messageSecurityProvider);

            new System.Net.Sockets.Socket(System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp).Dispose();

            // Connect to DNS server and get the record for the current server.
            IPHostEntry ipe = await Dns.GetHostEntryAsync(dnsServer);

            IPAddress  ipa  = ipe.AddressList[0];
            IPEndPoint ipep = new IPEndPoint(ipa, (int)UdpServices.Domain);

            byte[] recvBytes = null;

            switch (protocol)
            {
            case ProtocolType.Tcp:
            {
                recvBytes = await ResolveTcp(bDnsQuery, ipep);

                break;
            }

            case ProtocolType.Udp:
            {
                recvBytes = await ResolveUdp(bDnsQuery, ipep);

                break;
            }

            default:
            {
                throw new InvalidOperationException("Invalid Protocol: " + protocol);
            }
            }

            DnsQueryResponse dnsQR = new DnsQueryResponse();

            dnsQR.ParseResponse(recvBytes, protocol);

            return(dnsQR);
        }
Пример #15
0
        /// <PermissionSet>
        ///     <IPermission class="System.Net.DnsPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
        /// </PermissionSet>
        public Response Query(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
        {
            // Do stack walk and Demand all callers have DnsPermission.
            _dnsPermissions.Demand();

            var query = _requestBuilder.Build(host, queryType, queryClass, protocol);

            // Connect to DNS server and get the record for the current server.

            byte[] responseBytes = null;

            var resolver = _resolverFactory.Get(protocol);
            responseBytes = resolver.Resolve(query, _serverEndPoint);

            Trace.Assert(responseBytes != null, "Failed to retrieve data from the remote DNS server.");

            var response = _responseParser.ParseResponse(responseBytes);

            return response;
        }
Пример #16
0
        public async Task <DnsQueryResponse> Resolve(string host, NsType queryType, NsClass queryClass, ProtocolType protocol, TsigMessageSecurityProvider provider)
        {
            string dnsServer = string.Empty;

            IPAddressCollection dnsServerCollection = Tools.DiscoverDnsServerAddresses();

            if (dnsServerCollection.Count == 0)
            {
                throw new Exception("Couldn't detect local DNS Server.");
            }

            dnsServer = dnsServerCollection[0].ToString();

            if (String.IsNullOrEmpty(dnsServer))
            {
                throw new Exception("Couldn't detect local DNS Server.");
            }

            return(await Resolve(dnsServer, host, queryType, queryClass, protocol, provider));
        }
Пример #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="ms"></param>
        public void ParseRecordHeader(ref MemoryStream ms)
        {
            byte[] nsType       = new byte[2];
            byte[] nsClass      = new byte[2];
            byte[] nsTTL        = new byte[4];
            byte[] nsDataLength = new byte[2];

            // Read the name
            _name = DnsRecordBase.ParseName(ref ms);

            // Read the data header
            ms.Read(nsType, 0, 2);
            ms.Read(nsClass, 0, 2);
            ms.Read(nsTTL, 0, 4);
            ms.Read(nsDataLength, 0, 2);
            _nsType  = (NsType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsType, 0));
            _nsClass = (NsClass)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsClass, 0));

            _timeToLive = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(nsTTL, 0));
            _dataLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsDataLength, 0));
        }
Пример #18
0
        /// <PermissionSet>
        ///     <IPermission class="System.Net.DnsPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
        /// </PermissionSet>
        public Response Query(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
        {
            // Do stack walk and Demand all callers have DnsPermission.
            _dnsPermissions.Demand();

            var query = _requestBuilder.Build(host, queryType, queryClass, protocol);

            // Connect to DNS server and get the record for the current server.

            byte[] responseBytes = null;

            var resolver = _resolverFactory.Get(protocol);

            responseBytes = resolver.Resolve(query, _serverEndPoint);

            Trace.Assert(responseBytes != null, "Failed to retrieve data from the remote DNS server.");

            var response = _responseParser.ParseResponse(responseBytes);

            return(response);
        }
Пример #19
0
        private byte[] BuildDnsRequest(string host, NsType queryType, NsClass queryClass, ProtocolType protocol, IMessageSecurityProvider messageSecurityProvider)
        {
            // Combind the NsFlags with our constant flags
            ushort flags = (ushort)((ushort)_queryResponse | (ushort)_opCode | (ushort)_nsFlags);

            this._flags = flags;

            //NOTE: This limits the librarys ablity to issue multiple queries per request.
            this._nsType  = queryType;
            this._nsClass = queryClass;
            this._name    = host;

            if (messageSecurityProvider != null)
            {
                messageSecurityProvider.SecureMessage(this);
            }

            byte[] bDnsQuery = GetMessageBytes();

            // Add two byte prefix that contains the packet length per RFC 1035 section 4.2.2
            if (protocol == ProtocolType.Tcp)
            {
                // 4.2.2. TCP usageMessages sent over TCP connections use server port 53 (decimal).
                // The message is prefixed with a two byte length field which gives the message
                // length, excluding the two byte length field.  This length field allows the
                // low-level processing to assemble a complete message before beginning to parse
                // it.
                int len = bDnsQuery.Length;
                Array.Resize <byte>(ref bDnsQuery, len + 2);
                Array.Copy(bDnsQuery, 0, bDnsQuery, 2, len);
                bDnsQuery[0] = (byte)((len >> 8) & 0xFF);
                bDnsQuery[1] = (byte)((len & 0xFF));
            }

            return(bDnsQuery);
        }
Пример #20
0
 public Response(
     ushort transactionId,
     ushort flags,
     QueryResponse queryResponse,
     OpCode opCode,
     NsFlags nsFlags,
     RCode rCode,
     ushort questions,
     ushort answerRRs,
     ushort authorityRRs,
     string name,
     NsType nsType,
     NsClass nsClass,
     List <Record> additionalRecords,
     int bytesReceived,
     Record[] answers,
     Record[] authoritiveNameServers
     )
 {
     _bytesReceived          = bytesReceived;
     _answers                = answers;
     _authoritiveNameServers = authoritiveNameServers;
     _transactionId          = transactionId;
     _flags             = flags;
     _queryResponse     = queryResponse;
     _opCode            = opCode;
     _nsFlags           = nsFlags;
     _rCode             = rCode;
     _questions         = questions;
     _answerRRs         = answerRRs;
     _authorityRRs      = authorityRRs;
     _name              = name;
     _nsType            = nsType;
     _nsClass           = nsClass;
     _additionalRecords = additionalRecords;
 }
Пример #21
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="host"></param>
 /// <param name="queryType"></param>
 /// <param name="queryClass"></param>
 /// <param name="protocol"></param>
 /// <returns></returns>
 public DnsQueryResponse Resolve(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
 {
     return Resolve(host, queryType, queryClass, protocol, null);
 }
Пример #22
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="host"></param>
 /// <param name="queryType"></param>
 /// <param name="queryClass"></param>
 /// <param name="protocol"></param>
 /// <returns></returns>
 public Task <DnsQueryResponse> Resolve(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
 {
     return(Resolve(host, queryType, queryClass, protocol, null));
 }
Пример #23
0
        private byte[] BuildDnsRequest(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
        {
            // Combind the NsFlags with our constant flags
            ushort flags = (ushort)((ushort)_queryResponse | (ushort)_opCode | (ushort)_nsFlags);
            this._flags = flags;

            this._nsType = queryType;
            this._nsClass = queryClass;

            byte[] flagBytes = new byte[2];
            byte[] transactionId = new byte[2];
            byte[] questions = new byte[2];
            byte[] answerRRs = new byte[2];
            byte[] authorityRRs = new byte[2];
            byte[] additionalRRs = new byte[2];
            byte[] nsType = new byte[2];
            byte[] nsClass = new byte[2];

            // Prepare data for over the wire transfer
            transactionId = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_transactionId) >> 16));
            flagBytes = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_flags) >> 16));
            questions = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_questions) >> 16));
            answerRRs = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_answerRRs) >> 16));
            authorityRRs = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_authorityRRs) >> 16));
            additionalRRs = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_additionalRRs) >> 16));
            nsType = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsType) >> 16));
            nsClass = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsClass) >> 16));

            byte[] name = this.BuildQuery(host);

            // Build UPD DNS Packet to query
            MemoryStream ms = new MemoryStream();
            ms.Write(transactionId, 0, transactionId.Length);
            ms.Write(flagBytes, 0, flagBytes.Length);
            ms.Write(questions, 0, questions.Length);
            ms.Write(answerRRs, 0, answerRRs.Length);
            ms.Write(authorityRRs, 0, authorityRRs.Length);
            ms.Write(additionalRRs, 0, additionalRRs.Length);
            ms.Write(name, 0, name.Length);
            ms.Write(nsType, 0, nsType.Length);
            ms.Write(nsClass, 0, nsClass.Length);

            byte[] bDnsQuery = ms.ToArray();
            // Add two byte prefix that contains the packet length per RFC 1035 section 4.2.2
            if (protocol == ProtocolType.Tcp)
            {
                // 4.2.2. TCP usageMessages sent over TCP connections use server port 53 (decimal).
                // The message is prefixed with a two byte length field which gives the message
                // length, excluding the two byte length field.  This length field allows the
                // low-level processing to assemble a complete message before beginning to parse
                // it.
                int len = bDnsQuery.Length;
                byte[] bDnsQueryNew = new byte[len + 2];
                Array.Copy(bDnsQuery, 0, bDnsQueryNew, 2, len);
                bDnsQueryNew[0] = (byte)((len >> 8) & 0xFF);
                bDnsQueryNew[1] = (byte)((len & 0xFF));
            }
            return bDnsQuery;
        }
Пример #24
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="dnsServer"></param>
        /// <param name="host"></param>
        /// <param name="queryType"></param>
        /// <param name="queryClass"></param>
        /// <param name="protocol"></param>
        /// <param name="messageSecurityProvider">The instance of the message security provider to use to secure the DNS request.</param>
        /// <returns>A <see cref="T:DnDns.Net.Dns.DnsQueryResponse"></see> instance that contains the Dns Answer for the request query.</returns>
        /// <PermissionSet>
        ///     <IPermission class="System.Net.DnsPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
        /// </PermissionSet>
        public DnsQueryResponse Resolve(string dnsServer, string host, NsType queryType, NsClass queryClass, ProtocolType protocol, IMessageSecurityProvider messageSecurityProvider)
        {
            // Do stack walk and Demand all callers have DnsPermission.
            // FIXME _dnsPermissions.Demand();

            DnsQueryResponse dnsQR = new DnsQueryResponse();

            // Try a native query if it is supported.
            if (Tools.HasSystemDns)
            // CS0162 will fire when HasSystemDns is a constant.
#pragma warning disable 162
            {
                // See https://www.dns-oarc.net/oarc/services/replysizetest - 4k likely plenty.
                byte[] answer     = new byte[4096];
                int    answerSize = Tools.SystemResQuery(host, queryClass, queryType, answer);
                if (0 < answerSize)
                {
                    dnsQR.ParseResponse(answer, answerSize);
                    return(dnsQR);
                }
                else
                {
                    return(null);
                }
            }

            byte[] recvBytes = null;
            byte[] bDnsQuery = this.BuildDnsRequest(host, queryType, queryClass, protocol, messageSecurityProvider);

            IPAddress[] ipas = System.Net.Dns.GetHostAddresses(dnsServer);
            IPEndPoint  ipep = null;
            foreach (var addr in ipas)
            {
                if (addr.AddressFamily == AddressFamily.InterNetwork)
                {
                    ipep = new IPEndPoint(addr, (int)UdpServices.Domain);
                    break;
                }
            }
            if (null == ipep)
            {
                throw new Exception(string.Format("No IPv4 address found for hostname {0}", dnsServer));
            }

            switch (protocol)
            {
            case ProtocolType.Tcp:
            {
                recvBytes = ResolveTcp(bDnsQuery, ipep);
                break;
            }

            case ProtocolType.Udp:
            {
                recvBytes = ResolveUdp(bDnsQuery, ipep);
                break;
            }

            default:
            {
                throw new InvalidOperationException("Invalid Protocol: " + protocol);
            }
            }

            Trace.Assert(recvBytes != null, "Failed to retrieve data from the remote DNS server.");

            dnsQR.ParseResponse(recvBytes);

            return(dnsQR);
        }
Пример #25
0
        private byte[] BuildDnsRequest(string host, NsType queryType, NsClass queryClass, ProtocolType protocol, IMessageSecurityProvider messageSecurityProvider)
        {
            // Combind the NsFlags with our constant flags
            ushort flags = (ushort)((ushort)_queryResponse | (ushort)_opCode | (ushort)_nsFlags);
            this._flags = flags;

            //NOTE: This limits the librarys ablity to issue multiple queries per request.
            this._nsType = queryType;
            this._nsClass = queryClass;
            this._name = host;

            if(messageSecurityProvider != null)
            {
                messageSecurityProvider.SecureMessage(this);
            }

            byte[] bDnsQuery = GetMessageBytes();

            // Add two byte prefix that contains the packet length per RFC 1035 section 4.2.2
            if (protocol == ProtocolType.Tcp)
            {
                // 4.2.2. TCP usageMessages sent over TCP connections use server port 53 (decimal).
                // The message is prefixed with a two byte length field which gives the message
                // length, excluding the two byte length field.  This length field allows the
                // low-level processing to assemble a complete message before beginning to parse
                // it.
                int len = bDnsQuery.Length;
                Array.Resize<byte>(ref bDnsQuery, len + 2);
                Array.Copy(bDnsQuery, 0, bDnsQuery, 2, len);
                bDnsQuery[0] = (byte)((len >> 8) & 0xFF);
                bDnsQuery[1] = (byte)((len & 0xFF));
            }

            return bDnsQuery;
        }
Пример #26
0
 public DnsQueryResponse Resolve(string host, NsType queryType, NsClass queryClass, ProtocolType protocol, TsigMessageSecurityProvider provider)
 {
     foreach (var server in GetDnsServers ()) {
         try {
             return Resolve (server, host, queryType, queryClass, protocol, provider);
         } catch (Exception ex) {
             Console.WriteLine (string.Format ("DnsQueryRequest.Resolve: Could not resolve host {0}: {1}", host, ex));
         }
     }
     return null;
 }
Пример #27
0
 /// <summary>
 /// Initalise the <see cref="RecordHeader"/>
 /// </summary>
 /// <param name="name">The header name</param>
 /// <param name="nsType">The resource type</param>
 /// <param name="nsClass">The class type</param>
 /// <param name="timeToLive">The time to live</param>
 public RecordHeader(string name, NsType nsType, NsClass nsClass, int timeToLive)
 {
     _name = name;
     _nsType = nsType;
     _nsClass = nsClass;
     _timeToLive = timeToLive;
 }
Пример #28
0
 public IRecordParser Get(NsType type)
 {
     switch (type)
     {
         case NsType.A:
         {
             return _aParser;
         }
         case NsType.AAAA:
         {
             return _aaaaParser;
         }
         case NsType.MX:
         {
             return _mxParser;
         }
         case NsType.RP:
         {
             return _rpParser;
         }
         case NsType.MR:
         {
             return _mrParser;
         }
         case NsType.MB:
         {
             return _mbParser;
         }
         case NsType.MG:
         {
             return _mgParser;
         }
         case NsType.NS:
         {
             return _nsParser;
         }
         case NsType.CNAME:
         {
             return _cNameParser;
         }
         case NsType.PTR:
         {
             return _ptrParser;
         }
         case NsType.HINFO:
         {
             return _hInfoParser;
         }
         case NsType.MINFO:
         {
             return _mInfoParser;
         }
         case NsType.X25:
         {
             return _x25Parser;
         }
         case NsType.TXT:
         {
             return _txtParser;
         }
         case NsType.LOC:
         {
             return _locParser;
         }
         case NsType.SOA:
         {
             return _soaParser;
         }
         case NsType.SRV:
         {
             return _srvParser;
         }
         case NsType.AFSDB:
         {
             return _afsdbParser;
         }
         case NsType.ATMA:
         {
             return _atmParser;
         }
         case NsType.ISDN:
         {
             return _isdnParser;
         }
         case NsType.RT:
         {
             return _rtParser;
         }
         case NsType.WKS:
         {
             return _wksParser;
         }
         default:
         {
             return _unkowParser;
         }            
     }
 }
Пример #29
0
        byte[] GetMessageBytes(
            ushort transactionId,
            ushort flags,
            ushort questions,
            ushort answerRRs,
            ushort authorityRRs,
            string name,
            NsType nsType,
            NsClass nsClass
            )
        {
            var memoryStream = new MemoryStream();
            var data = new byte[2];

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(transactionId) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(flags) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(questions) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(answerRRs) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(authorityRRs) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(0) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = CanonicaliseDnsName(name, false);
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)nsType) >> 16));
            memoryStream.Write(data, 0, data.Length);

            data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)nsClass) >> 16));
            memoryStream.Write(data, 0, data.Length);

            _logger.Trace("The message bytes: {0}", DumpArrayToString(memoryStream.ToArray()));

            return memoryStream.ToArray();
        }
Пример #30
0
        public IRecordParser Get(NsType type)
        {
            switch (type)
            {
            case NsType.A:
            {
                return(_aParser);
            }

            case NsType.AAAA:
            {
                return(_aaaaParser);
            }

            case NsType.MX:
            {
                return(_mxParser);
            }

            case NsType.RP:
            {
                return(_rpParser);
            }

            case NsType.MR:
            {
                return(_mrParser);
            }

            case NsType.MB:
            {
                return(_mbParser);
            }

            case NsType.MG:
            {
                return(_mgParser);
            }

            case NsType.NS:
            {
                return(_nsParser);
            }

            case NsType.CNAME:
            {
                return(_cNameParser);
            }

            case NsType.PTR:
            {
                return(_ptrParser);
            }

            case NsType.HINFO:
            {
                return(_hInfoParser);
            }

            case NsType.MINFO:
            {
                return(_mInfoParser);
            }

            case NsType.X25:
            {
                return(_x25Parser);
            }

            case NsType.TXT:
            {
                return(_txtParser);
            }

            case NsType.LOC:
            {
                return(_locParser);
            }

            case NsType.SOA:
            {
                return(_soaParser);
            }

            case NsType.SRV:
            {
                return(_srvParser);
            }

            case NsType.AFSDB:
            {
                return(_afsdbParser);
            }

            case NsType.ATMA:
            {
                return(_atmParser);
            }

            case NsType.ISDN:
            {
                return(_isdnParser);
            }

            case NsType.RT:
            {
                return(_rtParser);
            }

            case NsType.WKS:
            {
                return(_wksParser);
            }

            default:
            {
                return(_unkowParser);
            }
            }
        }
Пример #31
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dnsServer"></param>
        /// <param name="host"></param>
        /// <param name="queryType"></param>
        /// <param name="queryClass"></param>
        /// <param name="protocol"></param>
        /// <param name="messageSecurityProvider">The instance of the message security provider to use to secure the DNS request.</param>
        /// <returns>A <see cref="T:DnDns.Net.Dns.DnsQueryResponse"></see> instance that contains the Dns Answer for the request query.</returns>
        /// <PermissionSet>
        ///     <IPermission class="System.Net.DnsPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
        /// </PermissionSet>
        public DnsQueryResponse Resolve(string dnsServer, string host, NsType queryType, NsClass queryClass, ProtocolType protocol, IMessageSecurityProvider messageSecurityProvider)
        {
            // Do stack walk and Demand all callers have DnsPermission.
            // FIXME _dnsPermissions.Demand();

            DnsQueryResponse dnsQR = new DnsQueryResponse();
            // Try a native query if it is supported.
            if (Tools.HasSystemDns)
                // CS0162 will fire when HasSystemDns is a constant.
            #pragma warning disable 162
            {
                // See https://www.dns-oarc.net/oarc/services/replysizetest - 4k likely plenty.
                byte[] answer = new byte[4096];
                int answerSize = Tools.SystemResQuery (host, queryClass, queryType, answer);
                if (0 < answerSize) {
                    dnsQR.ParseResponse (answer, answerSize);
                    return dnsQR;
                } else {
                    return null;
                }
            }

            byte[] recvBytes = null;
            byte[] bDnsQuery = this.BuildDnsRequest(host, queryType, queryClass, protocol, messageSecurityProvider);

            IPAddress[] ipas = System.Net.Dns.GetHostAddresses (dnsServer);
            IPEndPoint ipep = null;
            foreach (var addr in ipas) {
                if (addr.AddressFamily == AddressFamily.InterNetwork) {
                    ipep = new IPEndPoint(addr, (int)UdpServices.Domain);
                    break;
                }
            }
            if (null == ipep) {
                throw new Exception (string.Format ("No IPv4 address found for hostname {0}", dnsServer));
            }

            switch (protocol)
            {
                case ProtocolType.Tcp:
                    {
                        recvBytes = ResolveTcp(bDnsQuery, ipep);
                        break;
                    }
                case ProtocolType.Udp:
                    {
                        recvBytes = ResolveUdp(bDnsQuery, ipep);
                        break;
                    }
                default:
                    {
                        throw new InvalidOperationException("Invalid Protocol: " + protocol);
                    }
            }

            Trace.Assert(recvBytes != null, "Failed to retrieve data from the remote DNS server.");

            dnsQR.ParseResponse(recvBytes);

            return dnsQR;
        }
Пример #32
0
 public Task<DnsQueryResponse> ResolveAsync(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
 {
     return Task.Factory.StartNew<DnsQueryResponse> (() => {
         try {
             return Resolve (host, queryType, queryClass, protocol);
         } catch {
             // FIXME - uplevel this code to work with cancellation token.
             return null;
         }
     });
 }
Пример #33
0
        private byte[] BuildDnsRequest(string host, NsType queryType, NsClass queryClass, ProtocolType protocol)
        {
            // Combind the NsFlags with our constant flags
            ushort flags = (ushort)((ushort)_queryResponse | (ushort)_opCode | (ushort)_nsFlags);

            this._flags = flags;

            this._nsType  = queryType;
            this._nsClass = queryClass;

            byte[] flagBytes     = new byte[2];
            byte[] transactionId = new byte[2];
            byte[] questions     = new byte[2];
            byte[] answerRRs     = new byte[2];
            byte[] authorityRRs  = new byte[2];
            byte[] additionalRRs = new byte[2];
            byte[] nsType        = new byte[2];
            byte[] nsClass       = new byte[2];


            // Prepare data for over the wire transfer
            transactionId = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_transactionId) >> 16));
            flagBytes     = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_flags) >> 16));
            questions     = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_questions) >> 16));
            answerRRs     = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_answerRRs) >> 16));
            authorityRRs  = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_authorityRRs) >> 16));
            additionalRRs = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_additionalRRs) >> 16));
            nsType        = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsType) >> 16));
            nsClass       = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsClass) >> 16));

            byte[] name = this.BuildQuery(host);

            // Build UPD DNS Packet to query
            MemoryStream ms = new MemoryStream();

            ms.Write(transactionId, 0, transactionId.Length);
            ms.Write(flagBytes, 0, flagBytes.Length);
            ms.Write(questions, 0, questions.Length);
            ms.Write(answerRRs, 0, answerRRs.Length);
            ms.Write(authorityRRs, 0, authorityRRs.Length);
            ms.Write(additionalRRs, 0, additionalRRs.Length);
            ms.Write(name, 0, name.Length);
            ms.Write(nsType, 0, nsType.Length);
            ms.Write(nsClass, 0, nsClass.Length);

            byte[] bDnsQuery = ms.ToArray();
            // Add two byte prefix that contains the packet length per RFC 1035 section 4.2.2
            if (protocol == ProtocolType.Tcp)
            {
                // 4.2.2. TCP usageMessages sent over TCP connections use server port 53 (decimal).
                // The message is prefixed with a two byte length field which gives the message
                // length, excluding the two byte length field.  This length field allows the
                // low-level processing to assemble a complete message before beginning to parse
                // it.
                int    len          = bDnsQuery.Length;
                byte[] bDnsQueryNew = new byte[len + 2];
                Array.Copy(bDnsQuery, 0, bDnsQueryNew, 2, len);
                bDnsQueryNew[0] = (byte)((len >> 8) & 0xFF);
                bDnsQueryNew[1] = (byte)((len & 0xFF));
            }
            return(bDnsQuery);
        }
Пример #34
0
 public Response(
     ushort transactionId, 
     ushort flags, 
     QueryResponse queryResponse, 
     OpCode opCode, 
     NsFlags nsFlags, 
     RCode rCode, 
     ushort questions, 
     ushort answerRRs, 
     ushort authorityRRs, 
     string name, 
     NsType nsType, 
     NsClass nsClass,
     List<Record> additionalRecords,
     int bytesReceived,
     Record[] answers,
     Record[] authoritiveNameServers
     )
 {
     _bytesReceived = bytesReceived;
     _answers = answers;
     _authoritiveNameServers = authoritiveNameServers;
     _transactionId = transactionId;
     _flags = flags;
     _queryResponse = queryResponse;
     _opCode = opCode;
     _nsFlags = nsFlags;
     _rCode = rCode;
     _questions = questions;
     _answerRRs = answerRRs;
     _authorityRRs = authorityRRs;
     _name = name;
     _nsType = nsType;
     _nsClass = nsClass;
     _additionalRecords = additionalRecords;
 }
Пример #35
0
 // NOTE: the order of class & type w/libresolv are the opposite of this DnDns package!
 public static int SystemResQuery(string host, NsClass dnsClass, NsType dnsType, byte[] answer)
 {
     #if __IOS__
     return res_query(host, (int)dnsClass, (int)dnsType, answer, answer.Length);
     #else
     return -1;
     #endif
 }
Пример #36
0
        public DnsQueryResponse Resolve(string host, NsType queryType, NsClass queryClass, ProtocolType protocol, TsigMessageSecurityProvider provider)
        {
            string dnsServer = string.Empty;

            // Test for Unix/Linux OS
            if (Tools.IsPlatformLinuxUnix())
            {
                dnsServer = Tools.DiscoverUnixDnsServerAddress();
            }
            else
            {
                IPAddressCollection dnsServerCollection = Tools.DiscoverDnsServerAddresses();
                if (dnsServerCollection.Count == 0)
                    throw new Exception("Couldn't detect local DNS Server.");

                dnsServer = dnsServerCollection[0].ToString();
            }

            if (String.IsNullOrEmpty(dnsServer))
                throw new Exception("Couldn't detect local DNS Server.");

            return Resolve(dnsServer, host, queryType, queryClass, protocol, provider);
        }
Пример #37
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dnsServer"></param>
        /// <param name="host"></param>
        /// <param name="queryType"></param>
        /// <param name="queryClass"></param>
        /// <param name="protocol"></param>
        /// <param name="messageSecurityProvider">The instance of the message security provider to use to secure the DNS request.</param>
        /// <returns>A <see cref="T:DnDns.Net.Dns.DnsQueryResponse"></see> instance that contains the Dns Answer for the request query.</returns>
        /// <PermissionSet>
        ///     <IPermission class="System.Net.DnsPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
        /// </PermissionSet>
        public DnsQueryResponse Resolve(string dnsServer, string host, NsType queryType, NsClass queryClass, ProtocolType protocol, IMessageSecurityProvider messageSecurityProvider)
        {
            // Do stack walk and Demand all callers have DnsPermission.
            _dnsPermissions.Demand();

            byte[] bDnsQuery = this.BuildDnsRequest(host, queryType, queryClass, protocol, messageSecurityProvider);

            // Connect to DNS server and get the record for the current server.
            IPHostEntry ipe = System.Net.Dns.GetHostEntry(dnsServer);
            IPAddress ipa = ipe.AddressList[0];
            IPEndPoint ipep = new IPEndPoint(ipa, (int)UdpServices.Domain);

            byte[] recvBytes = null;

            switch (protocol)
            {
                case ProtocolType.Tcp:
                    {
                        recvBytes = ResolveTcp(bDnsQuery, ipep);
                        break;
                    }
                case ProtocolType.Udp:
                    {
                        recvBytes = ResolveUdp(bDnsQuery, ipep);
                        break;
                    }
                default:
                    {
                        throw new InvalidOperationException("Invalid Protocol: " + protocol);
                    }
            }

            Trace.Assert(recvBytes != null, "Failed to retrieve data from the remote DNS server.");

            DnsQueryResponse dnsQR = new DnsQueryResponse();

            dnsQR.ParseResponse(recvBytes, protocol);

            return dnsQR;
        }
Пример #38
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ms"></param>
        public void ParseRecordHeader(ref MemoryStream ms)
        {
            byte[] nsType = new byte[2];
            byte[] nsClass = new byte[2];
            byte[] nsTTL = new byte[4];
            byte[] nsDataLength = new byte[2];

            // Read the name
            _name = DnsRecordBase.ParseName(ref ms);

            // Read the data header
            ms.Read(nsType, 0, 2);
            ms.Read(nsClass, 0, 2);
            ms.Read(nsTTL, 0, 4);
            ms.Read(nsDataLength, 0, 2);
            _nsType = (NsType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsType, 0));
            _nsClass = (NsClass)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsClass, 0));

            _timeToLive = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(nsTTL, 0));
            _dataLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsDataLength, 0));
        }
Пример #39
0
        private void btnLookup_Click(object sender, EventArgs e)
        {
            NsType lookupType = (NsType)((FieldInfo)lstBxQueryType.SelectedValue).GetValue(null);

            DnsQueryRequest request = new DnsQueryRequest();

            DnsQueryResponse response = request.Resolve(txtDnsServer.Text, txtNameToLookup.Text, lookupType, NsClass.INET, ProtocolType.Udp);
            StringBuilder    sb       = new StringBuilder(1024);

            sb.Append("Bytes received: " + response.BytesReceived);
            sb.Append("\r\n");

            // Enumerate the Authoritive Name Servers Records
            sb.Append("Authoritive Name Servers:");
            sb.Append("\r\n");

            foreach (IDnsRecord record in response.AuthoritiveNameServers)
            {
                sb.Append(record.Answer);
                sb.Append("\r\n");
                sb.Append("  |--- RDATA Field Length: ");
                sb.Append(record.DnsHeader.DataLength);
                sb.Append("\r\n");
                sb.Append("  |--- Name: ");
                sb.Append(record.DnsHeader.Name);
                sb.Append("\r\n");
                sb.Append("  |--- NS Class: ");
                sb.Append(record.DnsHeader.NsClass);
                sb.Append("\r\n");
                sb.Append("  |--- NS Type: ");
                sb.Append(record.DnsHeader.NsType);
                sb.Append("\r\n");
                sb.Append("  |--- TTL: ");
                sb.Append(record.DnsHeader.TimeToLive);
                sb.Append("\r\n");
            }

            // Enumerate the Answer Records
            sb.Append("Answers:");
            sb.Append("\r\n");
            foreach (IDnsRecord record in response.Answers)
            {
                sb.Append(record.Answer);
                sb.Append("\r\n");
                sb.Append("  |--- RDATA Field Length: ");
                sb.Append(record.DnsHeader.DataLength);
                sb.Append("\r\n");
                sb.Append("  |--- Name: ");
                sb.Append(record.DnsHeader.Name);
                sb.Append("\r\n");
                sb.Append("  |--- NS Class: ");
                sb.Append(record.DnsHeader.NsClass);
                sb.Append("\r\n");
                sb.Append("  |--- NS Type: ");
                sb.Append(record.DnsHeader.NsType);
                sb.Append("\r\n");
                sb.Append("  |--- TTL: ");
                sb.Append(record.DnsHeader.TimeToLive);
                sb.Append("\r\n");
            }

            sb.Append("Additional Records");
            sb.Append("\r\n");
            foreach (IDnsRecord record in response.AdditionalRecords)
            {
                sb.Append(record.Answer);
                sb.Append("\r\n");
                sb.Append("  |--- RDATA Field Length: ");
                sb.Append(record.DnsHeader.DataLength);
                sb.Append("\r\n");
                sb.Append("  |--- Name: ");
                sb.Append(record.DnsHeader.Name);
                sb.Append("\r\n");
                sb.Append("  |--- NS Class: ");
                sb.Append(record.DnsHeader.NsClass);
                sb.Append("\r\n");
                sb.Append("  |--- NS Type: ");
                sb.Append(record.DnsHeader.NsType);
                sb.Append("\r\n");
                sb.Append("  |--- TTL: ");
                sb.Append(record.DnsHeader.TimeToLive);
                sb.Append("\r\n");
            }

            txtOutput.Text = sb.ToString();
        }