月度归档:2013年03月

路由追踪的原理和实现

Windows提供tracert命令追踪一个IP数据报从本地要目标主机经过的每个路由器的IP地址,在网络分析、网络故障诊断等方面有重要意义。

为了防止一个IP数据报中因为某些路由故障(如路由环路)而在网络逗留过长的时间导致网络环境出现进一步的恶化趋势,TCP/IP协议在IP数据报里设置了一个TTL(Time To Live)字段。在IP数据报被发送出来的时候TTL有一个初始值(如128),每经过一个路由器此值会被路由器执行减1操作,如果一个路由器发现它路由的某个IP数据报的TTL值被减1之后的结果为0,那么这个数据报将会被丢弃,然后路由器会发送一个内容为“TTL超时”的ICMP数据报通知这个IP数据报的发送者。利用这一点,可以用如下的办法实现路由追踪:

(1)构造一个TTL值为1,发往追踪目标的ICMP请求响应(Echo)数据报;
(2)发送数据报;
(3)等待回应,如果收到来自目标的ICMP响应(Reply)数据报则记录响应地址和耗时,并结束追踪;如果收到ICMP TTL超时数据报,则记录路由器地址和耗时,数据报TTL值加1,重复第(2)步,直到收到目标响应或超出最大跟踪跳数。

Windows下可以使用IcmpSendEcho函数来发送自定义TTL的ICMP请求数据报。http://msdn.microsoft.com/zh-cn/library/aa366050(v=VS.85).aspx

DNS协议及DNS客户端的实现

DNS(Domain Name System)是一个提供域名解析服务的分布式系统,主要功能是完成域名与其对应的IP地址之间的相互转换。网络中提供DNS服务的主机叫做DNS服务器,而向DNS服务器发起查询请求的主机叫做DNS客户端,客户端与服务器之间通过DNS协议这一种应用层协议来相互通信并交换数据。

DNS协议建立在UDP或TCP协议之上,DNS服务器开放UDP:53端口和TCP:53端口监听客户端发来的请求。一般情况下客户端通过UDP协议封装请求报文,服务器也用UDP协议封装回应报文;由于广域网中不适合传输过大的UDP数据包,因此规定当封装了DNS回应的UDP数据包长度可能超过512字节时,客户端应该使用TCP协议连接DNS服务器并传输请求和回应,具体包括以下两种情况:(1)客户端认为UDP回应包长度可能超过512字节,主动使用TCP协议;(2)客户端第一次使用UDP协议发送DNS请求,服务端发现UDP回应包会超过512字节,截断UDP包中的回应报文,并在回应报文中为TC字段置1以通知客户端该报文已经被截断,客户端收到之后再发起一次TCP请求。

DNS数据报由头部和记录部分组成,其中请求报文只有问题部分,而回应报文可以有问题部分、回答部分、授权部分和附加部分。
net

DNS头部包含了标识、标志以及各个记录部分的记录个数。net_dns_header

其中标识字段用于确定请求会话,DNS服务保证请求和其对应的回应报文中标识字段的值是相等的。标志字段被分成若干子字段,用于标识数据包的各个属性。DNS头部的C语言结构可以表示如下:

问题部分由问题记录组成,资源部分、授权部分和附加部分由资源记录组成,问题记录和资源记录的结构是不一样的。
问题记录的格式如下图所示
net_a_record
查询名字是将要查询的域名,域名是一个由圆点分为若干节的字符串,这里的名字也由若干节组成,每一节第一个字节是这一个节中包含字符的长度。如下图
net_query_name

查询类型一般是A(地址)记录,表示把域名转换为32位的IPv4地址。全部的查询类型如下所示

查询类别一般都为1(Internet)。

资源记录的格式如下图所示
net_res_record
其中前三个字段与问题记录一致。生存时间表示该DNS回应记录可以在主机缓存中生存的时间,以秒为单位。资源数据长度是紧随其后的资源数据的长度,资源数据的具体内容与域类型字段有关,在只考虑A类型的时候这里的记录是一个32位的IP地址。

为了使DNS报文尽可能短,DNS协议对于可能重复出现的域名节采取压缩策略,因此通常情况下在一个报文中不会存有完全相同的域名节。当出现重复的域名节时,域名节的第一个字节将不是这个节的字符长度,而是以11开头的一个指针,指向该节在报文中第一次出现的位置。
net_pointer

下面是一个用UDP协议实现的DNS客户端类(没有实现TCP方式),测试Demo运行结果如图所示

dns_resolver


最新的相关文章

DNS:域名系统(一)
DNS:域名系统(二)

我是程序员(一)

建了个博客,总得往里面填点东西。本来是想写一篇技术文的,刚才在 CSDN 上闲逛时发现了一个大概是老程序员的专访,内容是该程序员怎样在十年内自学编程成为大牛的。看到该前辈最初学习编程的缘由,不禁想到了自己。从写下第一行代码到现在,应该已经不止 10 年了,虽然现在也没有成为大牛,但也算在 10 多年断断续续的编码过程中有一些值得回味的经历,把它们写下来一方面回忆一下往事,另一方面怕以后把这些经历都忘了。

第一次听到“计算机”这个概念是小时候一个晴朗的夜晚,我和老爹走在回家的路上,老爹无意提到了一个不知哪听来的说法,他说有一种叫电脑的神奇机器,它什么事情都知道,甚至可以知道我们每一个人今天干了什么,昨天干了什么。不知为何这一番现在看来都不太靠谱的话当时极大地触动了我,我清楚地记得当时的我抬头看着月亮,想像着这种神秘的机器长什么样子,还记得那可能是中秋节,月亮很大很亮很圆。那时我大概只有五六岁,周围没有人见过电脑,想像中电脑的样子深深刻在脑子里。

转眼到了小学三年级。我念的那个学校算是市里比较落后的,但是居然建了一个计算机房。我是在三年级开学的时候知道这件事的,当时各小学都盛行周末的兴趣班。“有音乐班、美术班、电脑班……”报到时班主任孙老师介绍到。一听到电脑班,本来对兴趣班什么的毫无兴趣的我心里一震,怀着对电脑强烈的好奇果断地报了名。当时其它班一期 60 元,电脑班 100 元。

等到了周六,一大早我在学校的计算机房里第一次见到了电脑。不宽的教室里大概有 20 台电脑,只有讲台上的一台机器有硬盘,下面的机器是 NOVELL 网组建的无盘工作站(当时不懂,后来根据记忆推测的)。主机是卧式的,显示器很小(但是好像是纯平的?),没有鼠标,装着 DOS 6.22 操作系统。

从此每天都在盼望着周六的到来。在一个年轻的萌妹子老师的指导下,我很快学会了常用的 DOS 命令,知道了什么是文件,什么是目录,什么是分区,怎样用 DOS 命令对文件系统进行增删改查等操作。也是在那个时候我学会了五笔输入,当时的拼音输入法远没有现在这么先进,输入效率相当低,所以首选的输入法就是五笔,在电脑上用五笔输入的习惯一直保持到了现在。

兴趣班同时还教文字排版,文字编辑和打印是当时电脑的主要用途之一,用的软件当然是 WPS。运行在希望汉字系统上的 WPS(应该是雷军解锁版的)是我用过的第一个中国软件,软件界面上硕大的“香港金山公司”和求伯君的名字回想起来历历在目。WPS 让我对金山公司有了深刻的印象,但当时的我不会想到十多年后我会坐在金山公司大楼里写下这篇文章。

电脑兴趣班果然让我对电脑产生了极大的兴趣,我开始频繁跑书店买一些大人都看不懂的书来看,我家在一个小县城,当时书店里跟电脑有关的书实在不多。老爹对我的兴趣也持支持态度,有时出差会给我买一些书回来。书里讲的内容有的懂有的不懂,但还是学会了很多老师没教过的 DOS 命令,学了几个就在学校机房里实验。当时看到有一种叫批处理的文件真是让我欣喜若狂,甚至可以用批处理来写几个有意思的脚本了。有些书里还提到了一种用鼠标操作的、不用打命令的、界面和 DOS 完全不一样的操作系统,叫做 Windows。但是小学机房的电脑上没有安装 Windows,应该也没有能力运行 Windows,这是我当时最大的遗憾。(未完)

psb0 psb