首页 > 代码库 > C#编程实现DNS Client和Server(转)

C#编程实现DNS Client和Server(转)

我们大多数人使用DNS主要是用于域名解析,近期有个特殊的需求:通过DNS协议传递特殊数据。翻遍互联网,最终找到了一个强大的C# DNS工具库  ARSoft.Tools.Net library ,感谢CodePlex,感谢 AlexReinert !

关于DNS协议,请参考微软在线文档DNS的体系结构 或 RFC系列文档 。

我的要求很简单,把特定的DNS请求数据包发送到指定的服务器并获得返回结果。为了完成这个验证工作,你需要和我一样具备以下条件:

1.拥有一台具有外网地址的服务器,如:54.243.209.209;

2.设置防火墙策略,放行53/UDP端口的通讯;(非常重要,我测试的时候走了弯路-_-)

3.设置域名subA.mooo.com 的 A记录为 54.243.209.209

4.设置域名subB.mooo.com 的 NameServer为 subA.mooo.com

5.根据以上设置,但我们请求解析xxx.subB.mooo.com的域名时,54.243.209.209会收到来自DNS服务器的DNS请求数据包;

6.响应这个数据包就可以完成一次标准的DNS请求响应;

7.构造特殊的域名就可以实现特征数据的传递;

接下来,分别编写客户端和服务端代码。也可以参考官方文档中的样例:http://arsofttoolsnet.codeplex.com/ 配合WireShark抓包分析,能够很好地帮助您调试程序。

C#编程实现实现DNS请求客户端

新建一个C#项目,使用dotNet Framework 3.5作为运行环境。添加对库文件“ARSoft.Tools.Net.dll”的引用。编写如下代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using ARSoft.Tools.Net.Dns; namespace MyDNSClient{    /// <summary>    /// @auth shadu{AT}foxmail.com    /// @desc C# DNS Client    /// </summary>    class Program    {        static void Main(string[] args)        {            //ClientQuery("www.baidu.com");            ClientQuery("xxx.subB.mooo.com");            Console.ReadKey();        }         public static void ClientQuery(string domain)        {            DnsMessage dnsMessage = DnsClient.Default.Resolve(domain, RecordType.A);            if ((dnsMessage == null) || ((dnsMessage.ReturnCode != ReturnCode.NoError) && (dnsMessage.ReturnCode != ReturnCode.NxDomain)))            {                Console.WriteLine("DNS request failed");            }            else            {                foreach (DnsRecordBase dnsRecord in dnsMessage.AnswerRecords)                {                    ARecord aRecord = dnsRecord as ARecord;                    if (aRecord != null)                    {                        Console.WriteLine("DNS request successfully : {0}",aRecord.Address.ToString());                    }                }            }        }    }}

C#编程实现实现DNS响应服务端

新建一个C#项目,使用dotNet Framework 3.5作为运行环境。添加对库文件“ARSoft.Tools.Net.dll”的引用。编写如下代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using ARSoft.Tools.Net.Dns;using System.Net;  namespace DNSServer{    /// <summary>    /// @auth shadu{AT}foxmail.com    /// @desc C# DNS Server    /// </summary>    class Program    {        static void Main(string[] args)        {            using (DnsServer server = new DnsServer(IPAddress.Any, 10, 10, ProcessQuery))            {                server.Start();                Console.WriteLine("Press any key to stop server");                Console.ReadLine();            }        }         static DnsMessageBase ProcessQuery(DnsMessageBase message, IPAddress clientAddress, System.Net.Sockets.ProtocolType protocol)        {            message.IsQuery = false;            DnsMessage query = message as DnsMessage;             // 官方的样例文档中没有体现DNS请求发起者的IP,我在这里增加了。            Console.WriteLine("Client Address:{0}", clientAddress.ToString());             Console.WriteLine("query.Questions.Count:{0}", query.Questions.Count);            Console.WriteLine("query.Questions.ToString():{0}", query.Questions.ToString());            Console.WriteLine("query.Questions[0].ToString():{0}", query.Questions[0].ToString());            Console.WriteLine("query.Questions[0].GetType():{0}", query.Questions[0].GetType().ToString());             Console.WriteLine("query.Questions[0].Name:{0}", query.Questions[0].Name.ToString());            Console.WriteLine("query.Questions[0].RecordType:{0}", query.Questions[0].RecordType.ToString());            Console.WriteLine("query.Questions[0].RecordClass {0}", query.Questions[0].RecordClass.ToString());             if (query.Questions[0].Name.Contains("subB.mooo.com"))            {                 Console.WriteLine("Contains subB.mooo.com");                query.AnswerRecords.Add(new ARecord("xxx.subB.mooo.com", 3600, IPAddress.Parse("9.9.9.9")));                message.ReturnCode = ReturnCode.NoError;                return message;             }            else            {                Console.WriteLine("!!! not Contains mooo");                message.ReturnCode = ReturnCode.ServerFailure;                Console.WriteLine(message.ReturnCode.ToString());                 return message;            }        }    }}

服务端效果如图:


点击图片放大浏览

 

C#编程实现DNS Client和Server(转)