刚好解答了今天前辈讲解过程中我产生的问题。
原文链接http://www.zhihu.com/question/20717354
知乎是个好东西啊~~~
网络模型被OSI分成七层,TCP/IP协议大致对应了2、3、4、7层,分别是数据链路层、网络层、传输层、应用层,IP协议处于网络层上,它的工作原理说白了并不复杂:
- 整个互联网上所有的机器都有唯一一个IP地址对应。这并没有什么稀奇的,MAC地址也是唯一的,稀奇的在后面
- 机器的IP地址按照连接顺序进行了一定程度的分组,这样一个连续的IP段大致都在相同的路线上,这样路由器寻找特定IP地址的时候就方便多了,把整个地址空间分成若干个可能重叠的大段,每个大段一般这样表示:A.B.C.D/n,表示32位IP地址的前n位与A.B.C.D的前n位相同。比如192.168.1.0/24,所有前24位与192.168.1.0相同的都是这个网段的IP,由于IP地址8位一分组,24位就是前三段,也就是192.168.1.x。符合规范的这段连续的IP段就叫做一个子网。这种子网的表示方法叫做CIDR。
- 这种表示方法对人来说比较直观,但是计算机有另一种更快速的计算方法,对于A.B.C.D/n,我们构造一个前n位都是1、后面其他位都是0的IP地址,这个32位IP地址和A.B.C.D按位与的结果,就是前n位与A.B.C.D相同而后面其他位都是0的IP地址;如果这个32位IP地址和另一个IP地址与的结果,刚好与A.B.C.D与的结果相等,就说明这个IP地址和A.B.C.D的前n位相等,就说明新IP地址在CIDR范围内。我们把前n位都是1、后面其他位是0的地址也用IP地址的形式表示出来,那么192.168.1.0/24对应的就是255.255.255.0,这个就叫做子网掩码,掩码也就是mask,mask在计算机用语当中表示按位与的操作数,用来从目标数中取出特定的二进制位。也就是说IP+子网掩码是CIDR的另一种表示形式。
对于任意一台计算机或者路由器来说,它首先会有一些本地的链路,这些链路的IP地址都在各自特定的CIDR当中,这个子网叫做链路子网,链路子网中的IP地址都可以通过链路层协议直接访问,具体的访问方法与IP协议无关,在以太网当中是靠ARP,但是如果是WLAN,或者令牌环网,或者PPPoE,又会有所不同。比如子网是192.168.1.0/24,那么范围内所有IP地址都会直接调用链路层协议访问。表现在路由表中,就是这样一项:
192.168.1.0/24 -> link local, ifindex = XXX
即“192.168.1.0/24范围的IP通过XXX网卡的链路层协议直接访问”
如果还有其他链路,也会有相应的表项,比如说还有一个网卡上面的链路子网是111.222.1.0/24,那么就有另一项:
111.222.1.0/24 -> link local, ifindex = YYY
特别的,每个网卡上都会有一个IP地址,是本机的IP地址。当数据包发到这个IP地址的时候,设备就会正确理解“这个数据包是发给我自己的”,否则会理解为“这个数据包需要我代为转发”。这些本机的IP地址一定在链路层子网当中,比如说192.168.1.0/24中本机的IP地址是192.168.1.1,111.222.1.0/24中的IP地址是111.222.1.15,那么就有两个表项:
192.168.1.1/32 -> local
111.222.1.15/32 -> local
到local表示交给本机的更高层的协议栈,比如TCP/UDP去处理。否则会转发到其他机器。
我们注意到这些表项和刚才的表项有重叠的部分,比如说192.168.1.1/32其实包含在192.168.1.0/24里面。路由表的不同表项有不同的优先级,子网越小的越优先,也就是后面n越大的越优先,这样192.168.1.1/32就比192.168.1.0/24优先。