1、前言
foxmail新版中有1个《邮件特快专递》的功能。起先弄不懂如何用,后来知道要在 工具->系统选项 那边设置 本地DNShttp://www.wfuyu.com/server/的IP地址。
觉得这个新功能蛮好用的。不需要通过SMTP代理,可以直接通过本地往邮箱所在的邮件交换器发送邮件。在暑假1开始想在VC++中实现这个功能。用IRIS截包后,发现程序后mx8.263.net发送邮箱,不知道这个是甚么东西所以作罢。 后来才想到这个就是263.net的MX记录主机,原来特快专递的原理就是往这个主机上发送数据就行。
运行nslookup程序:
set type=mx
263.net
有了,有了,得到结果:
Non-authoritative answer:
263.net MX preference = 10, mail exchanger = mx06.263.net
263.net MX preference = 10, mail exchanger = mx08.263.net
263.net MX preference = 10, mail exchanger = mx09.263.net
263.net MX preference = 10, mail exchanger = mx11.263.net
263.net MX preference = 10, mail exchanger = mx12.263.net
263.net MX preference = 40, mail exchanger = mx03.263.net
263.net MX preference = 10, mail exchanger = mx01.263.net
没有错了。就是这个了。后来由于不知道怎样实现nslookup的功能,就放弃了,学了半个多月的C#。后来偶然在网上查找到了1些相干的文档。几次实验。把我的开发进程拿过来分享,我第1次写教程性文档。所以不规范的地方,请大家包涵。本文触及的域名、邮箱及IP均为真实的。
2、DNS协议原理
我认为,要想成为1个好的网络软件http://www.wfuyu.com,必须得读懂RFC文档。由于本文是面向大多广泛程序爱好者,所以我尽可能从细节上写,如果高手的话,可以跳过此部份。
DNS协议的相干RFC文档:
RFC1034-《DOMAIN NAMES - CONCEPTS AND FACILITIES》
RFC1035-《DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION》
网上的计算机用形如 220.162.75.1 这样称为IP地址的数字串来标识1台计算机。而如果每次访问1台计算机都是通过输入这样的东东来访问,那不就太可怕了?以是出了DNS这样的好东东,用要唆使其绑定的IP地址,当我们在阅读器内输入 http://zzsy.com 时,阅读器不知道网页该到哪里取,因而就向设定好的DNShttp://www.wfuyu.com/server/查询zzsy.com这个域名。DNShttp://www.wfuyu.com/server/会先寻觅自己的记录库,如果没有发现就转向上1级DNShttp://www.wfuyu.com/server/进行查询(转发要求)。把找到后的IP告知你的阅读器。这里边阅读器查询的记录类型是A记录。RFC1035文档第11页中定义有16种记录类型,而常见的有A(地址)记录、CNAME(别名)记录、MX(邮件交换)记录。我们本篇要关心的是MX记录。
查询的进程1般是:客户向DNShttp://www.wfuyu.com/server/的53端口发送UDP报文,DNShttp://www.wfuyu.com/server/收到落后行处理,并把结果记录仍以UDP报文的情势返回过来。
此UDP报文的1般格式:
+---------------------+
| 报文头 |
+---------------------+
| 问题 | 向http://www.wfuyu.com/server/提出的查询部份
+---------------------+
| 回答 | http://www.wfuyu.com/server/回复的资源记录
+---------------------+
| 授权 | 权威的资源记录
+---------------------+
| 格外的 | 格外的资源记录
+---------------------+
除报文头是固定的12字节外,其他每部份的长度均为不定字节数。
我们在这边关心的是报文头、问题、回答这3个部份。
其中报文头的格式:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
好家伙,是甚么鬼画符!
其中最上边是位的数字标识,0⑴5(注意,后边的10⑴5写成上下的情势了,1开始我楞没看懂)。
接下来是:
ID:占16位,2个字节。此报文的编号,由客户端指定。DNS回复时带上此标识,以唆使处理的对应请应要求。
QR:占1位,1/8字节。0代表查询,1代表DNS回复
Opcode:占4位,1/2字节。唆使查询种类:0:标准查询;1:反向查询;2:http://www.wfuyu.com/server/状态查询;3⑴5:未使用。
AA:占1位,1/8字节。是不是权威回复。
TC:占1位,1/8字节。由于1个UDP报文为512字节,所以该位唆使是不是截掉超过的部份。
RD:占1位,1/8字节。此位在查询中指定,回复时相同。设置为1唆使http://www.wfuyu.com/server/进行递归查询。
RA:占1位,1/8字节。由DNS回复返回指定,说明DNShttp://www.wfuyu.com/server/是不是支持递归查询。
Z:占3位,3/8字节。保存字段,必须设置为0。
RCODE:占4位,1/2字节。由回复时指定的返回码:0:无过失;1:格式错;2:DNS出错;3:域名不存在;4:DNS不支持这类查询;5:DNS谢绝查询;6⑴5:保存字段。
QDCOUNT:占16位,2字节。1个无符号数唆使查询记录的个数。
ANCOUNT:占16位,2字节。1个无符号数指明回复记录的个数。
NSCOUNT:占16位,2字节。1个无符号数指明权威记录的个数。
ARCOUNT:占16位,2字节。1个无符号数指明格外记录的个数。
其中每一个查询的资源记录格式:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
QNAME:不定长,表示要查询的域名。(两边的方框用 / 来表示不定长)
QTYPE:2字节,根据RFC1035及nslookup的帮助文档,我定义以下枚举类型:
enum QueryType //查询的资源记录类型。
{
A=0x01, //指定计算机 IP 地址。
NS=0x02, //指定用于命名区域的 DNS 名称http://www.wfuyu.com/server/。
MD=0x03, //指定邮件接收站(此类型已过时了,使用MX代替)
MF=0x04, //指定邮件中转站(此类型已过时了,使用MX代替)
CNAME=0x05, //指定用于别名的规范名称。
SOA=0x06, //指定用于 DNS 区域的“起始授权机构”。
MB=0x07, //指定邮箱域名。
MG=0x08, //指定邮件组成员。
MR=0x09, //指定邮件重命名域名。
NULL=0x0A, //指定空的资源记录
WKS=0x0B, //描写已知服务。
PTR=0x0C, //如果查询是 IP 地址,则指定计算机名;否则指定指向其它信息的指针。
HINFO=0x0D, //指定计算机 CPU 和操作系统类型。
MINFO=0x0E, //指定邮箱或邮件列表信息。
MX=0x0F, //指定邮件交换器。
TXT=0x10, //指定文本信息。
AAAA=0x1c,//IPV6资源记录。
UINFO=0x64, //指定用户信息。
UID=0x65, //指定用户标识符。
GID=0x66, //指定组名的组标识符。
ANY=0xFF //指定所有数据类型。
};
QTYPE:2字节。 根据RFC1035及nslookup的帮助文档,我定义以下枚举类型:
enum QueryClass //指定信息的协议组。
{
IN=0x01, //指定 Internet 种别。
CSNET=0x02, //指定 CSNET 种别。(已过时)
CHAOS=0x03, //指定 Chaos 种别。
HESIOD=0x04,//指定 MIT Athena Hesiod 种别。
ANY=0xFF //指定任何之前列出的通配符。
};
QTYPE中的A,MX,CNAME为经常使用,QCLASS中的IN为经常使用。
其中每一个回复的记录格式:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ NAME /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
NAME:回复查询的域名,不定长。
TYPE:回复的类型。2字节,与查询同义。唆使RDATA中的资源记录类型。
CLASS:回复的类。2字节,与查询同义。唆使RDATA中的资源记录类。
TTL:生存时间。4字节,唆使RDATA中的资源记录在缓存的生存时间。
RDLENGTH:长度。2字节,唆使RDATA块的长度。
RDATA:资源记录。不定义,依TYPE的不同,此记录的格示不同,通常1个MX记录是由1个2字节的唆使该邮件交换器的优先级值及不定长的邮件交换器名组成的。
这边陈述1下名称的组合情势。名称由多个标识序列组成,每个标识序列的首字节说明该标识符的长度,接着用是ASCII码表示字符,多个序列以后由字节0表示名字结束。其中某1个标识序列的首字符的长度若是0xC0的话,表示下1字节唆使不是标识符序列,而是唆使接下部份在本接收包内的偏移位置。
比如 bbs.zzsy.com 以.分开bbs、zzsy、com3个部份。每一个部份的长度为3、4、3
在DNS报文中的情势就如 3 b b s 4 z z s y 3 c o m 0
假设在包内的第12个字节位置存在有 4 z z s y 3 c o m 0 这样的名称了。
那此时有可能为:3 b b s 4 z z s y 0xC0 0x0C 这样的情势。
3、DNS协议实例讲授
说了这么多理论屁话,可能头都有两个大了吧。还是用1个实例的方法来讲明吧。
我选用著名的网络截包及协议分析工具IRIS 4.05,您可以从我的站点上下载:
http://itboy.cn/data/Iris405Full.rar
运行Iris,点击菜单的Filters 选 Port标签页 应用 53 端口后点肯定。
点击Iris工具栏上的绿色运行图标进行监听。
在windows中运行nslookup程序。
输入以下命令:
set type=mx
然后返回nslookup程序。
再输入命令:
yahoo.com.cn
会得到
yahoo.com.cn MX preference = 20, mail exchanger = mx5.mail.yahoo.com
yahoo.com.cn MX preference = 10, mail exchanger = mta-v1.mail.
=====================================================================
DNS报文格式:
该报文由12字节的首部和4个长度可变的字段组成。
标识字段由客户程序设置并有http://www.wfuyu.com/server/返回结果。
16bit的标志字段 以下:
QR:0表示查询报文,1表示响应报文
Opcode:通常值为0(标准查询),其他值为1(反向查询)和2(http://www.wfuyu.com/server/状态要求)。
AA:表示授权回答(authoritative answer).
TC:表示可截断的(truncated)
RD:表示期望递归
RA:表示可用递归
随后3bit必须为0
Rcode:返回码,通常为0(没有过失)和3(名字过失)
后面4个16bit字段说明最后4个变长字段中包括的条目数。
问题部份:
报文格式:
查询名为要查找的名字,它由1个或多个标示符序列组成。每一个标示符已首字节数的计数值来讲明该标示符长度,每一个名字以0结束。计数字节数必须是0~63之间。该字段无需填充字节。如:gemini.tuc.noao.edu
每一个问题有1个查询类型,通常查询类型为A(由名字取得IP地址)或PTR(取得IP地址对应的域名)
资源记录部份:
报文格式:
DNS最后3个字段,回答字段,授权字段和附加信息字段均采取资源记录RR(Resource Record)的相同格式。
域名是记录中资源数据对应的名字。它的格式和查询名字段格式相同。
类型说明R R的类型码。类通常为1,指I n t e r n e t数据。
生存时间字段是客户程序保存该资源记录的秒数。
资源数据长度说明资源数据的数量。该数据的格式依赖于类型字段的值。对类型1(A记录)资源数据是4字节的I P地址。
数据包DNS 查询:(DNS query)
0000 00 19 56 6e 19 bf 00 17 a4 1a b2 e0 08 00 45 00 ..Vn.... ......E.
0010 00 3b ed c6 00 00 80 11 e3 c3 ac 15 0f 04 ac 15 .;...... ........
0020 01 f9 04 a9 00 35 00 27 2f bd 3e 3a 01 00 00 01 .....5.' /.>:....
0030 00 00 00 00 00 00 03 77 77 77 06 67 6f 6f 67 6c .......w ww.googl
0040 65 02 63 6e 00 00 01 00 01 e.cn.... .
说明:
前面3段分别为以太网包头,ip包头和UDP包头。
从0020行后面开始为DNS数据包.
3e 3a 为标识字段
01 00 为标志字段,该字段设置了TC表示该报文是可截断的。
00 01 查询报文数量为1。
00 00 00 00 00 00 表示回答,授权和额外信息都为0。
03 77 77 77 06 67 6f 6f 67 6c 65 02 63 6e 00 表示查询的名字为
www.google.com
00 01 为类型,1表示A查询
00 01 为类,1表示Internet数据。
数据包 DNS response (DNS response)
0000 00 17 a4 1a b2 e0 00 19 56 6e 19 bf 08 00 45 00 ........ Vn....E.
0010 00 78 48 af 00 00 7d 11 8b 9e ac 15 01 f9 ac 15 .xH...}. ........
0020 0f 04 00 35 04 a9 00 64 75 db 3e 3a 81 80 00 01 ...5...d u.>:....
0030 00 03 00 00 00 00 03 77 77 77 06 67 6f 6f 67 6c .......w ww.googl
0040 65 02 63 6e 00 00 01 00 01 c0 0c 00 05 00 01 00 e.cn.... ........
0050 00 05 42 00 11 02 63 6e 01 6c 06 67 6f 6f 67 6c ..B...cn .l.googl
0060 65 03 63 6f 6d 00 c0 2b 00 01 00 01 00 00 00 5f e.com..+ ......._
0070 00 04 cb d0 21 65 c0 2b 00 01 00 01 00 00 00 5f ....!e.+ ......._
0080 00 04 cb d0 21 64 ....!d
说明:
前面3段分别为以太网包头,ip包头和UDP包头。
3e 3a 为标识字段
81 80 为标志字段,其中设置了QR = 1,RD = 1,RA = 1
00 01 问题数1,00 03 回答数3,其余两个为0。
03 77 77 77 06 67 6f 6f 67 6c 65 02 63 6e 00 表示查询的名字为
www.google.com
00 01 为类型,1表示A查询
00 01 为类,1表示Internet数据。
接下来为回答报文,
c0 0c 为域名指针
00 05 表示CNAME(规范名称)
00 01 类,表示为Internet数据
00 00 05 42 生存时间
00 11 数据长度
02 63 6e 01 6c 06 67 6f 6f 67 6c 65 03 63 6f 6d 00 为数据 cn.l.google.cn
然后接下来两段为另外两个回答。
最后的数据为IP地址
转自:http://blog.chinaunix.net/uid⑴2077794-id⑼1657.html
上一篇 Android源码之高仿爱奇艺
下一篇 远程centos修改yum源