一、网络基本层次:
1、数据链路层:
实现网卡接口的网络驱动程序,以往处理数据在物理媒介上的传输。数据链路层常用的协议有ARP(地址解析协议)和RARP(逆地址解析协议)。他们实现了ip地址和机器物理地址(mac地址,以太网,令牌环网,802.11无线网络都使用mac地址)之间的相互转换。
网络层使用ip来寻址一台机器,数据链路层使用物理地址来寻址一台机器。因此,网络层必须先将目标机器的ip地址转化成其物理地址,才能使用数据链路层提供的服务,这就是ARP协议的用途。
2、网络层:实现数据包的选路和转发。通常使用众多分级的路由器来连接分散的主机或局域网,因此通信的主机之间并不是直接相连的,而是通过多个中间节点(路由器)连接的。最核心的是ip协议。ip协议根据数据包的目的ip地址来决定如何投递它。如果数据包不能直接发送给目标主机,那么ip协议就为他寻找一个合适的下一跳路由器,必将数据包交付给路由器来转发。网络层还有一个重要的协议是ICMP协议(控制报文协议),用于网络连接。
8位类型字段用于区分报文类型,将控制报文分成两类:(1)差错报文(2)查询报文
3、传输层:为主机之间提供端口到端口的通信。传输层只关心通信的起始端和目的端,而不再乎数据包哦中专过程。
传输层协议主要有三个:tcp协议,udp协议,和sctp协议。
TCP(传输控制协议):为应用层提供可靠的,面向连接的和基于流的服务。TCP协议使用时超时重传,数据确认等方式来确保数据包被正确的发送至目的端,因此TCP服务是可靠的。使用TCP协议的通信的双方必须建立TCP连接,并在内核中为该连接维持一些必要的数据结构,比如连接的状态,读写缓冲区,以及诸多定时器等。通信结束时,双方必须关闭连接以释放这些内核数据。TCP协议是基于流的。基于流的数据没有边界长度的限制,它源源不断的从通信的一端流入另一端。发送端可以逐个字节的向数据流中写入数据,接收端也可以逐个字节的将它们读入。
UDP协议:(用户数据报协议)
SCTP协议:(流控制传输协议)是一种相对较新的传输层协议,它是为了因特网上传输电话信号而设计的。
4、应用层:应用层负责处理应用程序的逻辑。数据链路层,网络层和传输层负责处理网络通信细节,这部分必须既稳定而高效,因此他们都在内核空间中实现,而应用层则在用户空间实现,因为他负责处理众多的逻辑,比如文件传输,名称查询和网络管理等。如果应用层也在内核中实现,因为他负责处理众多逻辑,比如文件传输,名称查询和网络管理等这样会使内核变得非常大。
应用层协议有很多:(1)ping是应用程序,而不是协议,前面说他利用ICMP报文检测网络连接,是调试网络环境的必备工具。
(2)telnet协议是一种远程登录协议,它使我们能在本地完成远程任务。
(3)OSPF协议:是一种动态路由更新协议,用于路由器之间的通信,以告知对方各自的路由信息。
(4)DNS协议:提供机器域名到ip地址的转换。
二、封装:上层协议是如何使用下层协议提供的服务的那?其实这是通过封装实现的。应用程序在发送到物理层网络上之前,将沿着协议栈从上往下依次传递。每层协议都将在上层数据的基础上加上自己头部信息(有时还包括尾部)以实现该层的功能,这个过程就叫做封装。
经过TCP封装后的数据称为tcp报文段,或者简称tcp段。前文提到,tcp协议为通信双方维持一个连接,并且在内核中存储相关数据。这部分数据中的tcp头部信息和tcp内核缓冲区数据一起构成了tcp报文段。
当发送端应用程序使用send(或write)函数向TCP连接写入数据时,内核中的TCP模块首先把这些数据复制到与该链接对应的TCP发送缓冲区中,然后TCP模块调用ip模块提供的服务,传递包括TCP头部信息和TCP发送缓冲区中的数据,即TCP报文段。关于TCP报文段头部的细节,我们将在第3章讨论。
经过UDP封装厚的数据称为UDP数据报。UDP为应用程序的封装与TCP类似。不同的是,UDP无须为应用层数据保存副本,因为它提供的服务是不可靠的。当一个UDP数据包被发送成功之后,UDP内核缓冲区中的这个数据报就被丢弃了。
经过IP封装后的数据报称为ip数据报。ip数据报也包括头部信息和数据部分,其中数据部分就是一个TCP报文段、UDP报文段、或者ICMP报文(错误侦测与回报机制)目的是:让我们能够检测网络的连线状况,也能确保连线的准确性。
经过数据链路层封装的数据称为帧。传输媒介不同,帧的类型也不同。
以太网使用6字节的目的物理地址和6字节的源物理地址来表示通信双方。关于类型(type)字段,我们将在后面讨论。4字节的CRC字段对帧的其他部分提供循环冗余校验。
帧的最大传输单元,即帧最多能携带多少上层协议数据(ip数据报),通常受到网络类型的限制。
帧才是最终在物理网络上传送的字节序列。
三、分用:
当帧到达目的主机时,将沿着协议栈自底向上依次传递。各层协议依次处理帧中本层负责的头部数据,以获取所需的信息,并最终将处理后的帧交给目标应用程序。这个过程称为分用。分用是依靠头部信息中的类型自段实现的。
因为ip,arp,rarp协议都使用帧传输数据,所以帧的头部需要提供某个字段来区分他们。以太网为例,使用2字节的类型字段来表示上层协议。如果主机接收到的以太网帧类型字段的值为0x800,则帧的数据部分为IP数据报,以太网驱动程序将帧交付给ip模块。
同样,因为ICMP协议,TCP协议和UDP协议都使用IP协议所以ip数据报的头部采用16位的协议字段来区分它们。TCP报文段和UDP报文段则通过其头部的16位端口号字段来区分上层应用程序。比如dns协议对应的端口号是53,HTTP协议,超文本传输协议,对应的端口号是80.所有知名应用层协议实用的端口号都可在一个文件中找到。
帧通过上述分析分用步骤后,最终将封装前的原始数据报送至目标服务。
四、测试网络:
1、ARP协议工作原理:
ARP协议能实现任意网络层地址到任意物理地址的转换,其工作原理是:主机向自己所在的网络广播一个ARP请求,该请求包含目标主机的网络地址。此网络上其他机器都将会收到这个请求,但只有被请求的目标主机会回应一个ARP应答。,其中就包含自己的物理地址。
由图可知,ARP请求,应答报文的长度为28个字节。如果在加上以太网帧头部和尾部的18个字节,择一个携带ARP请求的报文的帧长度为64各字节。
(1)ARP高速缓存的查看和修改:
通常一个ARP维护一个高速缓存,其中包含经常访问或最近访问的机器的ip地址到物理地址的映射。这样就避免了ARP请求,提高了数据报的速度。
linux下可以使用arp命令来查看和修改ARP高速缓存。比如,
ernest-laptop在某一时可的ARP缓存内容如下:
kongming20 {192.168.1.109} at 08:00:27:53:10:67 {ether} on eth0?(192.168.1.1) at 14:e6:e4:93:5b:78 {ether} on eth0
其中第一项描述的是另一台测试机器kongming20(其ip地址,mac地址,与1-8描述一致),第二项描述的是路由器。下面两个语句则分别删除和添加一个ARP缓存项:
$ sudo arp -d 192.168.1.109 #删除kongming20对应的ARP缓存项
$ sudo arp -s 192.168.109 08:00:27:53:10:67#添加kongming20对应的ARP缓存项
(2)使用tcpdump观察arp通信过程。
为了清楚地了解ARP的运作过程,我们从ernest—laptop上执行telnet命令登录kongming20的echo服务(已经开启),并用tcpdump抓取这个过程中两台测试机器之间交换的以太网帧。具体操作如下:
$ sudo arp -d 192.168.1.109 #清除arp缓存中kingming20对应的项
$ sudo tcpdump -i eth() -ent '{dst 192.168.1.109 and src 192.168.1.108} or {dst 192.168.1.108 and src 192.168.1.109}'#如果没有特殊声明,抓包都在机器ernest—laptap上执行
$ telnet 192.168.1.109 echo #开启另一个终端执行telnet命令
Tring 192.168.1.109
connected to 192.168.1.109.
escape character is '^]'
^](回车)#输入ctrl +】并回车。
connection closed
在执行命令之前,应先清楚ARP缓存中与kongming20对应的项,否则ARP通信不被执行,我们也就没法抓取到期望的以太网帧。当执行telnet命令并在两台通信主机之间建立TCP连接后,输入ctrl +】以调出telnet程序的命令提示符,然后在telnet命令提示符后输入quit,退出telnet客户端程序(因为ARP通信在TCP连接建立之前就已经完成,故我们不关心后续内容)。tcpdump抓取到的众多数据包中,只有最靠前的两个和ARP通信有关系,现在将它们列出:
1、00:16:d3:5c:b9:e3>ff:ff:ff:ff:ff:ff,ethertype ARP {0x0806},length 42:request who-has 192.168.1.109 tell 192.168.1.108,length 28
2、08:00:27:53:10:67>00:16:d3:5c:b9:e3, ethertype ARP {0x86},length 60: reply 192.168.1.109 is-at 08:00:27:53:10:67,length 46
由tcpdump抓取的数据包本质上是以太网帧,我们通过命令的众多选项来控制帧的过滤(比如用dst和src制定通信的目的端ip地址和源端ip地址)和显示(用-e选项开启以太网头部信息的显示)。
第一个数据包中,ARP通信源端的物理地址是:00:16:d3:5c:b9:e3,目的端的物理地址是:ff:ff:ff:ff:ff:ff,这时以太网的广播地址,用以表示整个lan。该lan上的所有机器都会收到并处理这样的帧。数值0x806是以太网帧头部的类型字段的值,它表示分用的目标是ARP模块。帧长度是42字节(实际46字节,tcpdump 没有统计以太网帧尾部的4字节CRC字段),其中数据部分长度是28字节。。request表示这是一个ARP请求,who-has 192.168.1.109 tell 192.168.1.108 表示ernest-laptop要查询kongming20的ip地址。
第二个数据包中,ARP通信源端的物理地址是:08:00:27:53:10:67,目的端的物理地址是:00:16:d3:5c:b9:e3。reply表示这是一个arp应答协议。192.168.1.109 is-at 08:00:27:53:10:67则表示目标机器kongming20报告其物理地址。该以太网帧的长度伟0字节,可见它使用了填充字节来满足最小帧
长度
关于该图,(1)我们将两次传输的以太网按照图1-6所描述的以太网帧封装格式绘制在图的下半部分。
(2)ARP请求和应答是从以太网驱动程序发出的,而并非像途中描述从ARP模块直接发送到以太网上,所以我们将它们用虚线表示,这主要是为了体现携带ARP数据的以太网帧和其他以太网帧(比如携带ip数据包的以太网帧)的区别。
(3)路由器也将接受到以太网帧1,因为该帧是一个广播帧。不过很显然,路由器并没有回应其中的ARP请求,正如前文讨论的那样。
五、DNS工作原理
通常,我们使用域名来访问这台机器,而不直接使用iip地址,那么如何将机器的域名转换成ip地址:这就需要使用域名查询服务。域名查询服务有很多中实现方式,比如NIS(网络信息服务),DNS和本地静态文件等。
(1)DNS查询和应答报文详解:
DNS是一套分布式的域名服务系统。每个DNS服务器上都存放这大量的机器名和ip地址的映射,并且是动态更新的。众多网络客户端程序都使用DNS协议来向DNS服务器查询目标主机的ip地址。DNS查询和应答报文格式如下:
16位标识字段用于标记一对DNS查询和应答,以此来区分一个DNS应答是那个DNS查询的回应。
16位标志字段用于协商具体的通信方式和反馈通信状态。DNS报文头部的16位标志字段的细节如图:
(2)linux下访问DNS服务:
我们要访问DNS服务,就必须先知道DNS服务器上的IP地址。LINUX使用/etc/resolve.conf文件来存放DNS服务器的IP地址。
其中的两个IP地址分别是首选DNS服务器地址和备选服务器地址。文件中的注释语句”Generated by network manager“告诉我们,这两个DNS服务器地址是由网络管理程序写入的。
linux下一个常用的访问DNS服务器的客户端程序是host,比如下面的命令是向首选DNS服务器219.239.26.42 查询机器www.baidu.com的ip地址:
host命令的输出告诉我们,机器名www.baidu.com是www.a.shifen.com
的别名,并且该机器名对应两个ip地址。host命令使用DNS协议和DNS服务器通信,其-t选项告诉DNS协议使用哪种查询类型。我们使用的是a类型,即通过机器的域名来获得其ip地址。
(3)使用tcpdump观察DNS痛心的过程:
为了看清楚DNS通信的过程,下面我们将从ernest-laptop上运行命令以查询主机www.baidu.com 对应的ip地址,并使用tcpdump抓取lan上传输的以太网帧。具体操作如下:
这一次执行tcpdump抓包时,我们使用”port domain“来过滤包,标识只抓取使用domain(域名)服务的服务包,即DNS查询和应答报文。tcpdump的输出如下:
这两个数据包开始的ip指出,他们后面的内容描述的是ip数据报。tcpdump以ip地址,端口号的形式来描述通信的某一端:以>表示数据传输的方向,>前面是源端,后面是目的端。可见,第一个数据包是测试机器ernest-laptop向其首选的DNS服务器发送的DNS查询报文,第二个数据包是服务器反馈的DNS应答报文。
第一个数据包中,数值57428是DNS查询报文的标识值,因此该值也出现在DNS应答报文中。”+“表示启用递归查询标志。”A?“表示使用A类型的查询方式。”www.baidu.com“ 则是DNS查询问题中的查询名。括号中的数值31是DNS查询报文的长度。
第二个数据包中,”3/4/4“表示该报文中包含3个应答资源记录、4个授权资源记录和4个额外信息记录。”CNAME www.shifen.com A 119.75.218.77,A 119.75.217.56“则表示3个应答资源记录的内容。其中CNAME表示紧随其后的记录是机器的别名,A表示紧随其后的记录时uo地址。该应答报文的长度是226字节。
注意:我们抓包的时候没有开启tcpdump的-X选项(或着-x选项),如果使用-X选项,我们将能看到DNS报文的具体含义。
六、socket和tcp/ip协议族的关系。
前文提到,数据链路层,网络层,传输层协议在内核中事先的。以此操作系统需要实现一组系统调用,使得应用程序能够访问这些协议提供的服务。实现这组系统调用的api主要有两套:socket和xtl。xtl现在基本不再使用,本书仅讨论了,socket
与tcp、ip协议族与socket的关系。
由socket定义的这一组api提供如下两点功能:一是将应用程序数据从用户缓冲区中复制到tcp、udp内核发送缓冲区,以交付到内核来发送数据,或者是从内核tcp、udp接收缓冲区中复制数据到用户缓冲区,以读取数据;二是应用程序可以通过他们来修改内核中各层协议的某些头部信息或其它数据结构,从而精细的控制底层通信的行为。比如可以通过setsockopt函数来设置ip数据报在网络上的存活时间。
值得一提的是,socket是一套通用网络编程接口,它不但可以访问内核中tcpip协议栈,而且还可以访问网络协议栈。