热度 26
2012-8-30 09:28
972 次阅读|
0 个评论
W5100E01-AVR是为AVR开发者提供的W5100评估板。本文是W5100E01-AVR的用户手册,希望对大家有所帮助。今天我们接着前天的博文继续介绍: 第六部分在这里:W5100E01-AVR是什么?怎么用?(六)(用户手册V1.0版) http://blog.iwiznet.cn/?p=811 3.2.6.6.6 DNS客户端 在介绍DNS客户端设置之前,让我们简要的看一下DNS(域名系统)。 DNS系统用于将因特网域名转换成因特网IP地址,反之亦然。DNS由域名服务器和域名解析模块组成,域名服务器包含IP地址与域名之间的映射图,域名解析模块通过给域名服务器传输查询接收查询结果。 域名解析模块查询转换成本地域名服务器的IP地址或域名。本地域名服务器通过搜索DB(数据库)接收查询,并响应解析模块。如果域名解析模块找不到需要的信息,本地域名服务器就将接收到的查询发送给上一级域名服务器,接收到的响应就可以发送给域名解析模块。 如图3.33所示,DNS查询与DNS响应信息在域名解析系统和域名服务器之间的传送包括5部分,如图3.34所示。 Header部分包含固定12字节长度,其他4部分的长度是可变的。除了Header和Question部分,Answer、Authority和Additional部分被称为资源记录(RRs)。每一个Header、Question和RRs都有不同的格式。 DNS信息的Header部分保存信息类型、DNS查询类型和可变长度部分的统计信息。 在图3.35:Header部分格式中,当DNS信息是域名解析器到域名服务器的请求,QR字段值为0;反之,QR字段得值为1。当DNS信息为查询域名IP地址时,Opcode字段值为0;当它查询域名服务器状态时,Opcode字段值为2。 QDCOUNT、ANCOUNT、NSCOUNT与ARCOUNT字段统计可变长度的信息、由Question部分组成的代表区块数、Answer、Authority以及additional部分。组成Question部分的块如图3.36:Question部分格式所示,组成Answer、Authority和Additional部分的块如图3.37所示。 举例来说,如果QDCOUNT是1,ANCOUNT是0,NSCOUNT是10,ARCOUNT是10,那么组成Question部分的块如图3.36:Question部分格式所示。Answer、Authority和Additional部分由10块组成,如图3.37所示。 图3.37的NAME字段、图3.36的QNAME字段与RDDATA字段也可以得到可变长度。QNAME与NAME字段是可变长度字段,组成的格式和他们处理的每一个字段如图3.36所示。RDDATA可变长度字段和进程使用RDLENGTH字段的数据长度。 想了解更多,参见RFC1034和RFC1035。 DNS信息由表3-38所定义的数据类型操作,参见“inet/dns.h”。 如图3.33所示,DNS查询与DNS响应信息在域名解析系统和域名服务器之间的传送包括5部分,如图3.34所示。 域名解析模块基于gethostbyaddr()函数和gethostbyname()函数运作。gethostbyaddr()函数负责将因特网IP地址转换成因特网域名,gethostbyname()的功能正好相反。gethostbyaddr()函数和gethostbyname()函数测试域名服务器IP地址的设置和搜索W5100连接域名服务器所需信道。如果W5100的闲置信道存在,gethostbyaddr()函数和gethostbyname()函数用‘BYNAME’或‘BYIP’元素调用dns_query()。 更多gethostbyaddr() 函数和gethostbyname()函数的例子,参见3.2.5.3.章——Ping请求程序。 实际与域名服务器的连接是通过dns_query()函数执行的,gethostbyaddr()函数和gethostbyname()函数只负责报告dns_query()函数的结果。 dns_query()函数用于初始化域名服务器间的工作缓存区并基于‘BYNAME’和‘BYIP’查询类型创建Question部分的QNAME。如果查询类型是‘BYNAME’,那么当使用IP地址查询域名时,域名可以当成QNAME使用而不需要转换。 当查询类型是‘BYIP’时,那么当使用IP地址查询域名时,需要将IP地址转换成IP地址字符串,并在改变的IP地址字符串添加“in-addr.arpa”后使用QNAME。创建完QNAME后,需要为域名服务器间的工作创建UDP Socket,并通过调用dns_make_query()函数创建DNS请求信息。如果DNS请求信息被成功创建,就通过UDP Socket发送给域名服务器。发送完DNS请求信息后,它就接收DNS响应信息或等待,直到等待时间结束。 如果在等待期间从域名服务器接收到DNS响应信息,就使用dns_parse_response()函数分析接收到的DNS响应信息,dns_query()函数会基于查询类型返回IP地址或域名。 图3.39是dns_query()函数的流程图。 图3‑39: dns_query()函数 图3‑40: dns_makequery()函数 dns_makequery()函数创建需要发送给域名服务器的DNS请求信息。因为DNS请求信息只能通过Header和Question部分查询,dns_makequery()函数不需要创建RRs部分。如果你在dns_makequery()函数中查看Header部分,首先它将ID字段值与在域名服务期间工作的信息设置相同,这里ID设置成0x1122。为进一步实现域名服务器间的工作,ID值加1。QR、Opcode、AA、TC和RD字段通过MAKE_FLAG0()函数分别设置成QR_QUERY、OP_QUERY/OP_IQUERY、0、0、1,RA、Z和RCODE字段通过MAKE_FLAG1()函数分别设置成0、0、0。 因为count字段中,QDCOUNT、ANCOUNT、NSCOUNT和ARCOUNT都只有一个question,因此分别设置成1、0、0、0。 让我们来看一下Question部分,QNAME字段用于设置IP地址字符串。域名和IP地址字符串由1 byte的标签和最大可达63 byte的标签组成。为了识别QNAME的可变长度,QNAME字段通常以0作为结尾。图3.41所示是QNAME字段中,域名为www.wiznet.co.kr的实际传输例子。 因为count字段中,QDCOUNT、ANCOUNT、NSCOUNT和ARCOUNT都只有一个question,因此分别设置成1、0、0、0。 让我们来看一下Question部分,QNAME字段用于设置IP地址字符串。域名和IP地址字符串由1 byte的标签和最大可达63 byte的标签组成。为了识别QNAME的可变长度,QNAME字段通常以0作为结尾。图3.41所示是QNAME字段中,域名为www.wiznet.co.kr的实际传输例子。 Question部分的QTYPE字段需要设置成‘TYPE_PTR’,当它保存的域名认为是QNAME时,它的IP地址设置成‘TYPE_A’时,因为它包含在网络中,因此QCLASS字段需要设置成‘CLASS_IN’。 表3-41 是在QTYPE QCLASS字段使用的常量定义。 图3‑42: dns_parse_response()函数 图3.42 所示的dns_parse_response()函数分析了通过域名服务器接收的响应信息。dns_parse_response()函数检查发送给域名服务器的ID与响应信息的ID是否相同,它也检测接收到的响应信息是否为通过检查Header部分的QR字段的响应信息。如果接收到的信息是域名服务器的响应,改变的成功与否决定于检查Header部分的RCODE字段。 表3-42所示为RCODE字段使用的常量定义。 如果RCODE是RC_NO_ERROR,可变长度部分,例如Question、Answer、Authority和Additional部分被解析,因为在Answer部分设置了必要信息被分析和处理,而其他部分没有。如果你需要Authority和Additional部分的信息,你可以通过自己很轻松的获取。 Question部分通过调用dns_parse_question()函数处理Header部分的次数与QDCOUNT一样。Answer部分通过调用dns_parse_question()函数处理部分的次数与ANCOUNT一样多。 图3‑43: dns_parse_question()函数和dns_answer()函数 dns_parse_question()函数分析和处理Question部分。在DNS请求信息的Question部分并没有实际的信息,但是它必须被处理以获取Answer部分的开始位置。因为Question 部分的QNAME字段得到可变长度,parse_name()函数跳过了处理QNAME字段可变长度的过程、QTYPE和QCLASS字段。dns_answer()函数分析和处理Answer部分。Answer部分在转换确实产生作用时,在Answer部分的TYPE字段执行适当的程序。Answer部分的TYPE字段只有一种值,而不是来自TYPE_A 或TYPE_PTR,如表3-41 : QTYPE QCLASS字段的常量定义所示。如果域名变成IP地址,它可以从TYPE中得到改变的IP地址,域名可以从TYPE_PTR中获取,改变的域名或IP地址也可以通过parse_name()函数加工和提取。 图3‑44: parse_name()函数 parse_name()函数处理Question部分的QNAME字段或RRs部分的NAME、RDDATA字段。QNAME、NAME、RDDATA字段大多数的组成如图3.41:Question 部分的QNAME 字段传输实例所示,但是,它可以被压缩从而减少DNS信息的大小。压缩方法为2字节压缩,如果第1个字节——高字节的2位是‘11’,这就描述标签被压缩了。它包含第1个字节的偏移量,除了高字节的2位和第2个字节。这个偏移量是DNS信息的偏移量,表示从DNS信息的起点到标签存放位置的实际偏移量。如果压缩方案尝试重新使用已经在DNS信息中使用过的域名,就需要间接设置在DNS信息中的相关域名偏移量。图3.45所示为DNS信息压缩方案和应用实例。 图3.45的压缩方案实例是为了防止“F.ISI.ARPA”、“FOO.F.ISI.ARPA”、“ARPA”和ROOT. “F.ISI.ARPA” 没有压缩的情况下,在图3.41:Question部分的QNAME字段传输实例的格式中产生20的偏移量。在“FOO.F.ISI.ARPA,”中,因为剩下的除了“FOO”,都和先前处理的Name字段一样。“FOO”在没有压缩的情况下的处理流程如图3.41:Question部分的QNAME字段传输实例所示格式,剩下的名称做位移26处理。ROOT是最高级的域名,它使用0的Label Length字段处理。parse_name()函数在分析Name字段之前,检测Label Length Byte的高字节2位是否为11。如果是‘11’,相关Label就分析DNS信息中Lable所在的偏移量;如果不存在,Label的分析和处理过程如图3.41:Question部分的QNAME字段传输实例所示。 这是本文的第七部分内容,剩余的内容我们将会在今后的博文介绍,希望对大家有所帮助。欢迎大家的留言讨论。 更多有关W5100的博文请看这里: http://blog.iwiznet.cn/?page_id=329 全硬件TCP/IP嵌入式以太网控制器——W5100E01-AVR http://blog.iwiznet.cn/?p=432 开源硬件-开源思潮到了? http://blog.iwiznet.cn/?p=316 WIZnet员工Richard培训笔记: WIZnet核心技术和产品对比 http://blog.iwiznet.cn/?p=29 也可进入我们的官方网站或博客查看更多。 如果您对WIZnet的产品或是技术感兴趣,请随时与我们联系。 可以直接留言或登录WIZnet官方网站:http://www.iwiznet.cn 公司微博是: http://weibo.com/wiznet2012 公司博客是:http://blog.iwiznet.cn/