连网的不同电脑和设备之所以能互相通信,是因为它们都遵循着基本的协议和规则。提到协议分层,我们很容易联想到ISO-OSI的七层协议经典架构,但是TCP/IP协议栈的结构则稍有不同。如图所示:

TCP/IP协议族按照层次由上到下,层层包装。最上面的就是应用层了,这里面有http,ftp,等等我们熟悉的协议。而第二层则是传输层,著名的TCP和UDP协议就在这个层次。第三层是网络层,IP协议就在这里,它负责对数据加上IP地址和其他的数据以确定传输的目标。第四层是叫数据链路层,这个层次为待传送的数据加入一个以太网协议头,并进行CRC编码,为最后的数据传输做准备。再往下则是硬件层次了,负责网络的传输,这个层次的定义包括网线的制式,网卡的定义等等。发送协议的主机从上自下将数据按照协议封装,而接收数据的主机则按照协议从得到的数据包解开,最后拿到需要的数据。

基本术语

在学习协议之前,我们应该具备一些基本知识。 * IP地址 网络上每一个节点都必须有一个独立的Internet地址(也叫做IP地址)。现在,通常使用的IP地址是一个32bit的数字,也就是我们常说的IPv4标准,这32bit的数字分成四组,也就是常见的255.255.255.255的样式。IPv4标准上,地址被分为五类,我们常用的是B类地址。IP地址是网络号+主机号的组合。

  • 域名系统

域名系统是一个分布的数据库,它提供将主机名(就是网址啦)转换成IP地址的服务。负责域名和IP解析的主机叫DNS服务器。

  • RFC

RFC就是tcp/ip协议的标准文档,现在它一共有4000多个协议的定义,当然,我们所要学习的,也就是那么十几个协议而已。

  • 端口号(port)

这个号码是用在TCP,UDP上的一个逻辑号码,并不是一个硬件端口,我们平时说把某某端口封掉了,也只是在IP层次把带有这个号码的IP包给过滤掉了而已。

  • 应用编程接口

现在常用的编程接口有socket和TLI。而前面的有时候也叫做“Berkeley socket”,可见Berkeley对于网络的发展有多大的贡献。

数据链路层

数据链路层主要完成MAC-IP包的转换,为上层IP模块发送和接收包,发送和接收ARP和RARP请求和应答。ARP叫做地址解析协议,是用IP地址换MAC地址的一种协议,而RARP则叫做逆地址解析协议。据链路层的协议还是很多的,有我们最常用的以太网(就是平时我们用的网卡)协议,也有不太常见的令牌环,还有FDDI,当然,还有国内现在相当普及的PPP协议(就是adsl宽带),以及一个loopback协议。 有必要了解一下环回接口(loopback)协议。平时我们用127.0.0.1来尝试自己的机器服务器好使不好使。走的就是这个loopback接口。对于环回接口,有如下三点值得注意:

· 传给环回地址(一般是127.0.0.1)的任何数据均作为I P输入。\\
· 传给广播地址或多播地址的数据报复制一份传给环回接口,然后送到以太网上。这是 因为广播传送和多播传送的定义包含主机本身。
· 任何传给该主机IP地址的数据均送到环回接口。

TCP/IP协议之IP/ARP/RARP协议

这三个协议处于同一层,ARP协议用来找到目标主机的Ethernet网卡Mac地址,IP则承载要发送的消息。数据链路层可以从ARP得到数据的传送信息,而从IP得到要传输的数据信息。

  1.IP协议\\

IP协议是TCP/IP协议的核心,所有的TCP,UDP,IMCP,IGCP的数据都以IP数据格式传输。要注意的是,IP不是可靠的协议,这是说,IP协议没有提供一种数据未传达以后的处理机制–这被认为是上层协议–TCP或UDP要做的事情。所以这也就出现了TCP是一个可靠的协议,而UDP就没有那么可靠的区别。

  1.1 IP包头\\

来看看一个基本的IP包的结构:

其中TTL字段规定该数据包在穿过多少个路由之后才会被抛弃(这里就体现出来IP协议包的不可靠性,它不保证数据被送达),某个ip数据包每穿过一个路由器,该数据包的TTL数值就会减少1,直到为零自动抛弃该包。在IPV4中这个字段的最大值也就是255,但根据系统的不同,这个数字也不一样,一般是32或者是64,Tracerouter这个工具就是用这个原理工作的,tranceroute的-m选项要求最大值是255,也就是因为这个TTL在IP协议里面只有8bit。

  1.2 IP路由选择\\

  当一个IP数据包准备好了的时候,IP数据包(或者说是路由器)是如何将数据包送到目的地的呢?它是怎么选择一个合适的路径来“送货”的呢?
  最特殊的情况是目的主机和主机直连,那么主机根本不用寻找路由,直接把数据传递过去就可以了。这就要靠ARP协议了,后面会讲到。
  稍微一般一点的情况是,主机通过若干个路由器(router)和目的主机连接。那么路由器就要通过ip包的信息来为ip包寻找到一个合适的目标来进行传递,比如合适的主机,或者合适的路由。路由器或者主机将会用如下的方式来处理某一个IP数据包。

· 如果IP数据包的TTL(生命周期)以到,则该IP数据包就被抛弃。\\
· 搜索路由表,优先搜索匹配主机,如果能找到和IP地址完全一致的目标主机,则将该包发向目标主机\\
· 搜索路由表,如果匹配主机失败,则匹配同子网的路由器,这需要“子网掩码(1.3.)”的协助。如果找到路由器,则将该包发向路由器。
· 搜索路由表,如果匹配同子网路由器失败,则匹配同网号路由器,如果找到路由器,则将该包发向路由器。
· 搜索路由表,如果以上都失败了,就搜索默认路由,如果默认路由存在,则发包
· 如果都失败了,就丢掉这个包。


  1.3 子网寻址\\

  IP地址的定义是网络号+主机号。但是现在所有的主机都要求子网编址,也就是说,把主机号在细分成子网号+主机号。最终一个IP地址就成为 网络号码+子网号+主机号。例如一个B类地址:210.30.109.134。一般情况下,这个IP地址的前半部分是网络号,后半部分是子网号+主机号。至于有多少位代表子网号这个问题上,这没有一个硬性的规定,取而代之的则是子网掩码,子网掩码是由32bit的二进制数字序列,形式为是一连串的1和一连串的0,例如:255.255.255.0(二进制就是11111111.11111111.11111111.00000000)对于刚才的那个B类地址,因为210.30是网络号,那么后面的109.134就是子网号和主机号的组合,又因为子网掩码只有后八bit为0,所以主机号就是IP地址的后八个bit,就是134,而剩下的就是子网号码–109。

2. ARP协议
数据链路层的以太网的协议中,每一个数据包都有一个MAC地址头么?每一块以太网卡都有一个唯一的MAC地址,那么IP包是如何知道这个MAC地址的?这就是ARP协议的工作。

ARP(地址解析)协议是一种解析协议,本来主机是完全不知道这个IP对应的是哪个主机的哪个接口,当主机要发送一个IP包的时候,会首先查一下自己的ARP高速缓存(就是一个IP-MAC地址对应表缓存),如果查询的IP-MAC值对不存在,那么主机就向网络发送一个ARP协议广播包,这个广播包里面就有待查询的IP地址,而直接收到这份广播的包的所有主机都会查询自己的IP地址,如果收到广播包的某一个主机发现自己符合条件,那么就准备好一个包含自己的MAC地址的ARP包传送给发送ARP广播的主机,而广播主机拿到ARP包后会更新自己的ARP缓存(就是存放IP-MAC对应表的地方)。发送广播的主机就会用新的ARP缓存数据准备好数据链路层的的数据包发送工作。
一个典型的arp缓存信息如下,可在任意一个系统里面用“arp -a”命令查询。通常这样的高速缓存是有时限的,一般是20分钟(伯克利系统的衍生系统)。“arp -d“命令可以用来删除高速缓存。

ICMP协议/ping/traceroute

ICMP是IP协议的附属协议。IP层用它来与其他主机或路由器交换错误报文和其他重要信息。Ping和Traceroute都使用了ICMP。
ICMP协议大致分为两类,一种是查询报文,一种是差错报文。其中查询报文有以下几种用途:

1. ping查询(不要告诉我你不知道ping程序)\\
2. 子网掩码查询(用于无盘工作站在初始化自身的时候初始化子网掩码)\\
3. 时间戳查询(可以用来同步时间)\\

而差错报文则产生在数据传送发生错误的时候。就不赘述了。
ICMP的应用–ping
ping可以说是ICMP的最著名的应用,当我们某一个网站上不去的时候。通常会ping一下这个网站。它是利用ICMP协议包来侦测另一个主机是否可达。ping程序来计算间隔时间,并计算有多少个包被送达。用户就可以判断网络大致的情况。
ICMP的应用–Traceroute

Traceroute是用来侦测主机到目的主机之间所经路由情况的重要工具,它的原理是首先给目的主机发送一个TTL=1(的UDP数据包,而经过的第一个路由器收到这个数据包以后,就自动把TTL减1,而TTL变为0以后,路由器就把这个包给抛弃了,并同时产生 一个主机不可达的ICMP数据报给主机。主机收到这个数据报以后再发一个TTL=2的UDP数据报给目的主机,然后刺激第二个路由器给主机发ICMP数据 报。如此往复直到到达目的主机。这样,traceroute就拿到了所有的路由器ip。从而避开了ip头只能记录有限路由IP的问题。

有人要问,怎么知道UDP到没到达目的主机呢?这就涉及一个技巧的问题,TCP和UDP协议有一个端口号定义,而普通的网络程序只监控少数的几个号码较小的端口,比如说80,比如说23,等等。而traceroute发送的是端口号>30000的UDP报,所以到达目的主机的时候,目的主机只能发送一个端口不可达的ICMP数据报给主机。主机接到这个报告以后就知道,主机到了,从而有了完整的路由信息。

Traceroute程序里面提供了一些很有用的选项,甚至包含了IP选路的选项,请察看man文档来了解这些,这里就不赘述了。

路由常识

下面是一个简单的Linux下的路由表:

对于一个给定的路由器,可以打印出五种不同的flag:U表明该路由可用;G表明该路由是到一个网关,如果没有这个标志,说明和Destination是直连的,而相应的Gateway应该直接给出Destination的地址;H表明该路由是到一个主机,如果没有该标志,说明Destination是一个网络,换句话说Destination就应该写成一个网络号和子网号的组合,而不包括主机号(主机号码处为0),例如 192.168.11.0; D表明该路由是为重定向报文创建的;M该路由已经被重定向报文修改。
U没啥可说的,G说明这是一个网关,如果你要发数据给Destination,IP头应该写Destination的IP地址,而数据链路层的MAC地址就应该是GateWay的Mac地址了;反之,如果没有G标志,那么数据链路层和IP层的地址应该是对应的。H说明了Destination的性质,如果是H的,则说明该地址是一个完整的地址,既有网络号又有主机号,那么再匹配的时候就既要匹配网络号,又要匹配主机号;反之,Destination就代表一个网络,在匹配的时候只要匹配一下网络号就可以了。

这样,IP选路的方式就可以更加具体化了。如下:

1. 首先用IP地址来匹配那些带H标志的DestinationIP地址。\\
2. 如果1失败就匹配那些网络地址。\\
3. 如果2失败就发送到Default网关\\

顺便提一下那个GenMask(还记得子网掩码么),它指定了目的地址的子网号,例如第三条的子网就是1。

一般,我们在配置好一个网络接口的时候,一个路由就被直接创建好了。当然我们也可以手动添加路由。用route add命令就可以了。
而当一个IP包在某一个路由器的时候发现没有路由可走,那么该路由器就会给源主机发送“主机不可达”或者“网络不可达”的ICMP包来报错。

xxxx 在网络中传输数据包,在网络层中就有IP包的概念。 DNAT(Destination Network Address Translation,目的地址转换) 通常被叫做目的映射。而SNAT(Source Network Address Translation,源地址转换)通常被叫做源映射。