第二十二章 DNS22.1 DNS例程概述 W7500EVB的DNS例程,主要实现用W7500EVB通过DNS协议解析域名,获取该域名的IP地址信息。使用前先了解下DNS协议。 22.2 DNS协议简介 DNS是计算机域名系统或域名解析服务器(Domain Name System 或Domain Name Service) 的缩写,它是由解析器以及域名服务器组成的。它保存了一张域名(domain name)和与之相对应的IP地址的表,并为Internet上的主机分配域名地址和IP地址,域名和IP地址之间是一一对应的。 DNS域名解析是把域名指向网站空间IP,让人们通过域名可以方便地访问到网站。IP地址是网络上标识站点的数字地址,为了方便记忆,所以采用域名来代替IP地址标识站点地址 22.3 Internet域名结构 通常Internet主机域名的一般结构为:主机名、三级域名、二级域名、顶级域名。 ICANN定义了域名的命名采用层次结构的方法。包括:顶级域名,二级域名。每个域都有不同的组织来管理,而这些组织又可将其子域分给下级组织来管理。 顶级域名TLD(Top Level Domain)分为三大类: 1. 国家顶级域名nTLD(cn - 中国、uk - 英国、us - 美国等) 2. 国际顶级域名iTLD(.int,国际性组织可在.int下注册) 3. 通用顶级域名gTLD(.com - 商业组织、.edu - 教育机构、.org - 非赢利性组织、.gov -政府部门、.biz - 公司或企业等) 更多通用顶级域名如下表所示: 通用顶级域名 | 描述 | 通用顶级域名 | 描述 | aero | 航空机构 | int | 国际机构 | biz | 公司或企业 | mil | 军事机构 | com | 商业机构 | museum | 博物馆 | coop | 合作机构 | name | 个人网站 | edu | 教育机构 | net | 网络服务机构 | gov | 政府部门 | org | 非赢利性组织 | info | 信息提供 | pro | 专业机构 |
二级域名: 我国将二级域名划分为“ 类别域名”和“行政域名”两大类。 类别域名(ac--科研机构、com--商业组织、edu--教育机构、gov--政府部门、net--网络服务机构、org--各种非赢利组织) 行政域名(bj--北京、sh--上海、nm--内蒙等) 组织内域名: 当一个组织拥有一个域的管理权后,它可以决定是否需要进一步划分层次。例如:CERNET网络中心将“.edu”域划分为多个三级域,将三级域名分配给各个大学与教育机构。同时某大学也可以决定是否将自己得到的三级域划分为多个四级域,将四级域分配给下属部门或主机。 图22.3.1 DNS域名结构图 22.4 DNS协议解析过程 1、在浏览器中输入www.baidu.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。 2、如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。 3、如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找首选的DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。 4、如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。 5、如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。本地DNS服务器收到IP信息后,将会联系负责.com域的这台服务器。这台负责.com域的服务器收到请求后,如果自己无法解析,它就会找一个管理.com域的下一级DNS服务器地址给本地DNS服务器。当本地DNS服务器收到这个地址后,就会找www.baidu.com域服务器,重复上面的动作,进行查询,直至找到www.baidu.com主机。 6、如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管如何,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。 图22.4.1 DNS查询过程 22.5 DNS协议例程解析 DNS例程初始化部分与Network install例程一致,不了解的可以参照Network install例程解析章节。 了解了DNS的工作原理,下面我们来看一下在W7500EVB中的程序是如何处理DNS消息,获取一个域名的IP地址的过程。在本示例中,DNS的报文处理主要由dns.c中定义的函数来处理。一般来讲,为了提高通信的效率,DNS采用UDP协议进行通信,DNS服务器默认的UDP端口是53。这些内容在我们的dns.c实际代码中都体现了出来。 和以前章节的代码一样,main函数在初始化完成后,在主循环里面做DNS消息处理。当一个域名被成功解析后,通过对dns_ok这个变量的判断,主循环将不再和DNS服务器通信。当出现DNS解析失败时,主循环将会不断重试。下面主要讲解DNS执行函数DNS_run();。 [mw_shl_code=applescript,true]1. int8_t DNS_run(uint8_t * dns_ip, uint8_t * name, uint8_t * ip_from_dns)
2. {
3. int8_t ret;
4. struct dhdr dhp;
5. uint8_t ip[4];
6. uint16_t len, port;
7. int8_t ret_check_timeout;
8. socket(DNS_SOCKET, Sn_MR_UDP, 0, 0); // 打开DNS的Socket端口
9. #ifdef _DNS_DEBUG_
10. printf("> DNS Query to DNS Server: %d.%d.%d.%d\r\n",dns_ip[0],dns_ip[1],dns_ip[2],dns_ip[3]);
11. #endif
12. len = dns_makequery(0, (char *)name, pDNSMSG, MAX_DNS_BUF_SIZE);
13. sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);//给DNS服务器发送解析信息
14. while (1)
15. {
16. if ((len = getSn_RX_RSR(DNS_SOCKET)) > 0)
17. {
18. if (len > MAX_DNS_BUF_SIZE) len = MAX_DNS_BUF_SIZE;
19. len = recvfrom(DNS_SOCKET, pDNSMSG, len, ip, &port);//接收服务器应答信息
20. #ifdef _DNS_DEBUG_
21. printf("> Receive DNS message from %d.%d.%d.%d(%d). len = %d\r\n", ip[0], ip[1], ip[2], ip[3],port,len);
22. #endif
23. ret = parseDNSMSG(&dhp, pDNSMSG, ip_from_dns);
24. break;
25. }
26. // Check Timeout
27. ret_check_timeout = check_DNS_timeout();
28. if (ret_check_timeout < 0)
29. {
30. #ifdef _DNS_DEBUG_
31. printf("> DNS Server is not responding : %d.%d.%d.%d\r\n", dns_ip[0], dns_ip[1], dns_ip[2], dns_ip[3]);
32. #endif
33. return 0; // timeout occurred
34. }
35. else if (ret_check_timeout == 0)
36. {
37. #ifdef _DNS_DEBUG_
38. printf("> DNS Timeout\r\n");
39. #endif
40. sendto(DNS_SOCKET, pDNSMSG, len, dns_ip, IPPORT_DOMAIN);
41. }
42. }
43. close(DNS_SOCKET);//关闭Socket
44. return ret;
45. }[/mw_shl_code] 第8行是初始化DNS的Socket端口,第12行是用来解析来自DNS服务器的回复,第13行是给DNS服务器发送解析信息,第18~19是判断是否有接收到DNS服务器发送的应答,第23行是解析来自DNS服务器的回复信息然后跳出while并关闭Socket,回到主函数将解析完的IP地址打印出来。 至此,DNS例程代码解析就结束了。将DNS例程编译烧录后打印串口信息结果如图22.5.1。 图22.5.1 DNS例程打印结果
|