上一篇文章《DIY一个DNS查询器:了解DNS协议》中讲了DNS查询协议的原理和数据结构。经过两个星期的开发,完成了该查询器的编写。期间也遇到了一些问题,如:

1资源记录(Resource Record)中的RDData内容的格式。

2关于压缩编码的指针问题。

3代码冗余结构不清晰。

尤其是压缩编码的问题,困扰了我很久,找了很多中文资料,都说到当长度的值为“192”的时候为指针,下一字节的内容即偏移的位置,但是在过程中却发现存在该值为“193”的情况,一直不解了好久。这里我给解释下:

假设第13字节内容为:05-6c-69-78-69-6e-02-6d-6e

翻译为“5-l-i-x-i-n-2-m-e”

而其后的某个地方,同样出现了lixin.me的字符串,那么就会使用指针编码:"c0-0c”。

c0十进制是192,代表下面的内容是一个指针,0c是个地址,指向了data[12]的位置。

而为什么会出现193呢,也好理解,因为用一个字节的内容来表示偏移,顶多也只能偏移256个字节,那么假设udp包有500个字节长,而要指向第300字节就无能为力了。因此实际上的偏移量不是由oc这个字节内容决定的,正确的偏移量是:(Cn-C0)*256+0c。

如果值为193,下一字节为1,那么具体偏移就是 (193-192)*256+1 。

还有一点要注意到就是可变长度的Name字段以什么为结尾。有3中结尾方式:

1.长度+内容+~+长度0

2. 偏移标识+偏移量

3.长度+内容+~+偏移标识+偏移量

能成功解决该问题,主要还是靠资料,虽然知道rfc1034和rfc1035里面一定有我要的内容,可惜外文比较难懂,一直看不下去,通过搜索得到的中文和少量外文资料也没说清楚。最后还得感谢《TCP-IP详解卷一:协议》的第14章Dns协议的介绍,虽然只有短短的17页,但还是帮我解决了问题。所以在同样搞协议的同学,不妨弄本先去瞧瞧,或者遇到问题也可以先去看看。

现在来说说这个程序了。

我按dns协议的结构把项目分成 MyDnsHeader.cs、MyDnsQuestion.cs、MyDnsRecord.cs 这样的3个大结构。

发送dns请求时只需要构造MyDnsHeader和MyDnsQuestion结构,然后通过GetBytes()函数得到构造好的字节数组,然后通过udp发送出去。然后接受来自服务器的响应,将接收到的字节数组通过Parse(byte[] recvData)方法让3个结构去解析,最后通过这些结构的属性字段获取相应的查询信息。

其中的资源记录,目前能分析 A记录、SOA记录、TXT记录、CNAME记录、MX记录、NS记录。

示例代码:

MyDns mydns = new MyDns();//

//想8.8.8.8域名服务器查询lixin.me这个域名的a记录, 
         if (!mydns.Search(“lixin.me”QueryType.A, “8.8.8.8”,null )) 
         {

//如果服务器返回错误信息,则显示错误的内容

MessageBox.Show(mydns.header.RCODE.ToString()); 
             return; 
         } 
         txtInfo.Clear(); 
         txtInfo.AppendText (string.Format ("回复记录数:{0}\n",mydns.header.ANCOUNT) ); 
         txtInfo.AppendText(string.Format("回复额外记录数:{0}\n", mydns.header.ARCOUNT )); 
         txtInfo.AppendText(string.Format("回复权威记录数:{0}", mydns.header.NSCOUNT ));

txtContent.Clear(); 
         foreach (MyDnsRecord item in mydns.record.Records) 
         {

//循环资源记录,并打印出来。 
             txtContent.AppendText(item.QType.ToString() + "   " + item.RDDate.ToString()+"\n"); 
         }

界面截图:

代码下载及浏览:

我把代码放在了CodePlex.com 上面了。地址为:http://mydnspackage.codeplex.com/

欢迎园友测试。如果发现错误,请告知我。

DIY一个DNS查询器:程序实现的更多相关文章

  1. linux命令行学习-dig(DNS查询器)

    在web开发中.总要熟悉的就是http协议.而发起一个http開始前最先要经历的一个过程就是DNS解析.简单说就是域名怎样终于解析到实际serverip的过程. 而在研究DNS解析和排除DNS解析类故 ...

  2. Java内部DNS查询实现和参数设置

    一.Java内部DNS查询 Java使用域名查询时,用的自己内部的域名实现机制,最后都是交给InetAddress去做DNS解析. 源码分析参考:http://blog.arganzheng.me/p ...

  3. 基于nodejs的DNS查询工具

    开始这个实例之前,我们简单谈一下Node.js吧,Node.js是一个由JavaScript书写而成的强大Web开发框架,它让开发强壮的.伸缩性良好的服务器端Web应用变得更加简单.容易.这种技术诞生 ...

  4. python dns查询与DNS传输漏洞查询

    前言: 昨天晚上在看DNS协议,然后想到了 DNS传输漏洞.便想写一个DNS查询与DNS传输漏洞查询 DNS传输漏洞介绍: DNS传输漏洞:若DNS服务器配置不当,可能导致匿名用户获取某个域的所有记录 ...

  5. DIY:从零开始写一个 SQL 构建器

    最近在项目中遇到了一个棘手的问题,因为 EF Core 不支持直接生成 Update 语句,所以这个项目就用到了 EFCore.Plus 来实现这个功能,但是 EFCore.Plus 对 SQLite ...

  6. 【云开发】10分钟零基础学会做一个快递查询微信小程序,快速掌握微信小程序开发技能(轮播图、API请求)

    大家好,我叫小秃僧 这次分享的是10分钟零基础学会做一个快递查询微信小程序,快速掌握开发微信小程序技能. 这篇文章偏基础,特别适合还没有开发过微信小程序的童鞋,一些概念和逻辑我会讲细一点,尽可能用图说 ...

  7. 分享一个绿色版本 sql server 查询器,

    首先感谢原作者 源码来原于网络 此查询器增加了一些功能, 可以高亮显示 导出sql 语句    可以把左边树型拖入脚本编辑器 http://pan.baidu.com/s/1dDjaSbn

  8. 转载 DNS查询流程简介

    转载请注明出处:http://blog.csdn.net/luotuo44/article/details/45545059 DNS(domain name system),读者们或多或少都听过,就是 ...

  9. 【转】DNS查询过程

    DNS查询过程 DNS的查询过程是指在客户端通过DNS服务器将一个IP地址转换为一个FQDN(Fully Qualified Domain Name,完全合格的域名),或将一个FQDN转化为一个IP地 ...

随机推荐

  1. 转: WebRTC音视频引擎研究(1)--整体架构分析

    转自: http://blog.csdn.net/temotemo/article/details/7530504   目录(?)[+]   WebRTC技术交流群:234795279 原文地址:ht ...

  2. Six ways to think like a journalist!

    Journalists have the ability to state a thing more clearly. What can we learn from them to help us r ...

  3. sql的一些知识_通配符

    like操作符 通配符只能用于字符串查询 % 指任意字符出现任意次数,包括0次,不包括NULL SELECT username,weight,age FROM userinfo WHERE usern ...

  4. php.ini的载入位置

    php.ini文件找不到,载入WINDOS下的,但找不到,后来强制-c查找是OK的.思考,为什么载入window下的ini文件.1.可能是有一个默认路径.2.可能没有路径.默认载入. 问题解决:htt ...

  5. 【LeetCode-面试算法经典-Java实现】【002-Add Two Numbers (单链表表示的两个数相加)】

    [002-Add Two Numbers (单链表表示的两个数相加)] 原题 You are given two linked lists representing two non-negative ...

  6. web微信开发

    群里接收消息时,使用广播,但需要刷新页面才能接收到广播内容. - 轮询: 定时每秒刷新一次,当群不活跃时,群里的每个客户端都在刷新,对服务端压力太大. - 长轮询:客户端连服务端,服务端一直不断开,也 ...

  7. [Android5 系列—] 1. 构建一个简单的用户界面

    前言 安卓应用的用户界面是构建在View 和ViewGroup 这两个物件的层级之上的. View 就是一般的UI组件.像button,输入框等. viewGroup 是一些不可见的view的容器,用 ...

  8. spring 接收_header 作为get请求的httpheader

    今天项目遇到一个问题,我们项目用户验证和权限验证的信息(licence)是在http头中设置的,百度了一下,只有ajax才能设置头信息,form表单是无法设置的,但是我突然想起springMVC关于f ...

  9. Jenkins + Maven + TestNG参数化调用测试用例

      希望实现的场景:Jenkins中的Job可针对不同浏览器,不同环境,运行不同的测试用例集,但测试用例只保持一份. 具体实现的思路:在运行Jenkins Job时传入参数,运行 mvn test 命 ...

  10. FFmpeg编码详细流程

    FFmpeg在编码一个视频的时候的函数调用流程.为了保证结构清晰,其中仅列出了最关键的函数,剔除了其它不是特别重要的函数. 函数背景色 函数在图中以方框的形式表现出来.不同的背景色标志了该函数不同的作 ...