先注明 本文所有内容都是基于底层是以太网或iee802.3 封装的数据链路层进行讨论的,不包括点对点网络。

其中的ip协议指的也是ipv4.

数据链路层以太网和IEEE 802封装

以太网 是 TCP/IP 主要使用的 一种使用带冲突检测的载波侦听多路接入方式的 局域网组网技术。速率是10Mb/s(可以提升),地址为48bit

IEEE 下的802委员会 在 以太网发布之后几年,也公布了一项组网计数,不幸的是,802.2 和802.3 定义了一个与以太网不同的帧格式。

tcpip详解书籍目录(吐血整理TCPIP)(1)

以太网的类型字段后就是数据部分,但是IEEE802.3

802.3标准定义的帧和以太网的帧都有最小长度要求。以太网规定数据部分最少46字节,802.3至少为38字节。为了保证这一点,必须在不足的空间插入填充(pad)字节。

环回口/loopback

环回口是一个虚拟的接口。127开头的A类地址就分配给了环回口。

当收到数据包时,判断若目的IP地址与本机IP地址一致(或者收到多播、广播地址,且本机属于多播、广播地址)时,网卡就会将数据发送给环回接口。此时数据包还是会经过协议栈,只是到网络层时,会传到环回接口。所以环回一般会被用于检测本机协议栈是否正常(环回接口不会经过网卡)

单播组播广播:分别向局域网下的单个主机/ 某一组主机 /所有主机 发送数据包。

最大传输单元 MTU

无论是以太网还是IEEE802.3 ,对数据帧都有一个长度的限制

以太网是1500字节,IEEE802.3是1492。 如果ip层传来的数据包大于MTU需要进行分片。

路径MTU

当数据需要跨网络传递时,由于各个网络的链路层MTU 可能不同,为了使数据包能够一次性通过所有经过的网络,需要找到这个传递路径上的一个最小的MTU,我们称之为路径MTU。

MTU 的确定是通过ICMP协议 去实现的。下文会讲到。

几个基本概念路由器 和 网关

网关是用来连接两个不同的网络的。

网关是网络中的一个角色,指的是一个“网络”中的出口。路由器是一种设备。

路由器可以实现网关的功能,但是路由器功能不仅仅是实现网关。

网关可以由路由器实现,但是也不仅仅是由路由器实现。

交换机

交换机实现了特定网络内的数据交换。同一台主机

ip 协议

ip协议是TCP/ip协议族中最核心的协议,协议族里其他同层或上层协议都使用ip数据报格式传送数据。该协议提供了一个无连接的不可靠的传输数据报传输服务。

  • 无连接: ip协议并不维护后续数据报的状态信息(这个特性亦称无状态)。每个数据报是独立的,这也说明发送ip数据报并不需要按顺序接受,因为他们之间是独立的。对于同样的目的地,可能不同的数据包会选择不同的路径,导致先发的不一定先到。
  • 不可靠: ip协议不能保证IP数据报能成功地到达目的地。IP仅提供最好的传输服务。如果发生某种错误时,如某个路由器暂时用完了缓冲区,IP有一个简单的错误处理算法:丢弃该数据报,然后发送ICMP消息报给信源端。任何要求的可靠性必须由上层来提供(如TCP)。

tcpip详解书籍目录(吐血整理TCPIP)(2)

由上图的ip首部图可以看到,ip表示长度的bit长度为16,也就是可以说明ip的数据报最长的长度为2^16-1=65535个字节。(当然,在实际传输过程中,大多数链路层都会对其进行分片)

TTL

(time-to-live)生存时间字段设置了数据报可以经过的最多路由器数。它指定了数据报的生存时间。TTL的初始值由源主机设置(通常为32或64),一旦经过一个处理它的路由器,它的值就减去1。当该字段的值为0时,数据报就被丢弃,并发送ICMP报文通知源主机。

校验和

发送时先把每16个bit进行一次二进制反码求和,存为检验和字段。

接收方收到后也对每16个bit进行一次相同计算过程,如果没有任何差错,最后的计算结果应该为全1。如果不全1

,那么IP就丢弃收到的数据报。但是不生成差错报文,由上层去发现丢失的数据报并进行重传。

路由选择

IP路由选择是逐跳地(hop-by-hop)进行的。除了直接和主机相连的目的地,IP并不知道到达任何目的的完整路径。数据报在各站的传输过程中目的IP地址始终不变,但是封装和目的链路层地址在每一站都可以改变。

IP层既可以配置成路由器也可以配置成主机。当今的大多数多用户系统,包括几乎所有的Unix系统,都可以配置成一个路由器。本质上的区别在于主机从不把数据报从一个接口转发到另一个接口,而路由器则要转发数据报。

IP层在内存中有一个路由表。当收到一份数据报并进行发送时,它都要对该表搜索一次。当数据报来自某个网络接口时,IP首先检查目的IP地址是否为本机的IP地址之一或者IP广播地址。如果是本机地址,数据报就被送到由IP首部协议字段所指定的协议模块进行处理。如果数据报的目的不是这些地址,那么(1)如果IP层被设置为路由器的功能,那么就对数据报进行转发(也就是说,像下面对待发出的数据报一样处理);否则(2)数据报被丢弃。

子网寻址和子网掩码 这里直接省略了

arp和RARP(地址解析)

ARP的功能是在32 bit的IP地址和采用不同网络技术的硬件地址之间提供动态映射。这个过程是自动完成的,一般应用程序用户或系统管理员不必关心。

tcpip详解书籍目录(吐血整理TCPIP)(3)

RARP是被那些没有磁盘驱动器的系统使用(一般是无盘工作站或X终端),它需要系统管理员进行手工设置。

ARP 地址解析协议

知道主机的IP地址并不能让内核发送数据帧给主机。内核(如以太网驱动程序)必须知道目的端的硬件地址才能发送数据。arp就是用来通过ip地址获取mac地址的协议

tcpip详解书籍目录(吐血整理TCPIP)(4)

工作原理

源主机 向局域网内的所有主机发送一个arp广播,内容里有自己的ip和mac以及目标ip,广播的意思翻译过来大致是“谁有这个目的地址A,请回复我你的mac地址”。

如果有主机的ip地址确实是这目的地址,就会回复一个单播包,并附带上自己的mac地址。

其他ip不是这个目的地址的主机也并非什么偶读不干,它们会缓存这个源主机的ip和mac地址。

#todo ip 的寻址过程?ARP高速缓存

ARP高效运行的关键是由于每个主机上都有一个ARP高速缓存。这个高速缓存存放了最近Internet地址到硬件地址之间的映射记录。高速缓存中每一项的生存时间一般为20分钟,起始时间从被创建时开始算起。

可以使用arp -a 命令查看

arp代理

正常逻辑,arp的回复是一个主机附带上自己的mac地址去回复源主机。但是这个工作,可以交给路由器。只要路由器知道自己下属的主机的mac地址,那么在arp请求跨网络传递到该路由器时,该路由器可以自己直接回复arp包,并附带上路由器自己的mac地址。 这时源主机其实并不知道 这个mac地址是不是真的目的主机的地址,但是既然收到了回应,源主机就会开始发送数据帧。传递到目的路由器后,路由器再交给真正的目的主机。

tcpip详解书籍目录(吐血整理TCPIP)(5)

为什么要有ARP代理? 路由器的一个重要功能是把局域网广播包限制在该网内,不让扩散,否则会造成网络风暴。ARP Request是个广播包,它询问的对象若在同一个局域网内,就会回答。但如果查询对象不在同一个局域网,那怎么办呢?为了解决这个问题,路由器就提供一个服务:代理ARP.

还有什么方法来解决跨局域网的地址查询?若主机配置了默认网关,在查询MAC地址的对象位于局域网之外的时候,可以把查询任务交给默认网关

代理arp的优缺点?

优点

最主要的一个优点就是能够在不影响其他router的路由表的情况下在网络上添加一个新的router,这样使得子网的变化对主机是透明的proxy ARP应该使用在主机没有配置默认网关或没有任何路由策略的网络上

负面影响:

  1.增加了某一网段上ARP流量

  2.主机需要更大的ARP table来处理IP地址到MAC地址的映射

  3.安全问题,比如ARP欺骗(spoofing)

  4.不会为不使用ARP来解析地址的网络工作

  5.不能够概括和 推广网络拓扑

免费arp

它是指主机发送ARP查找自己的IP地址。通常,它发生在系统引导期间进行接口配置的时候。

作用:

  1. 可以确定局域网内是否还有别的主机也设定了相同的ip地址。正常来说,免费arp广播不应该有回应,如果有回应说明这个ip地址在局域网内已经存在,这样主机就会产生错误日志,提醒网络管理员ip设置有问题。
  2. 可以更新 其他主机的上对于该主机的arp缓存。(由于这个原因,如果有人伪造arp请求影响就很大,会影响整个局域网内的主机)。
RARP/逆地址解析协议

RARP 的 头部格式基本上和ARP 没什么区别

诞生原因

具有本地磁盘的系统引导时,一般是从磁盘上的配置文件中读取IP地址。但是无盘机,如X终端或无盘工作站,则需要采用其他方法来获得IP地址,也就是rarp。

工作原理

网络上的每个系统都具有唯一的硬件地址,它是由网络接口生产厂家配置的。无盘系统的RARP实现过程是从接口卡上读取唯一的硬件地址,然后发送一份RARP请求(一帧在网络上广播的数据),请求某个主机响应该无盘系统的IP地址(在RARP应答中)。当无盘系统从RARP应答中收到它的IP地址后,它将发送TFTP请求来读取引导映象。

RARP服务器的复杂性
  • 服务器一般要为多个主机(网络上所有的无盘系统)提供硬件地址到IP地址的映射。该映射包含在一个磁盘文件中(在Unix系统中一般位于/etc/ethers目录中)。由于内核一般不读取和分析磁盘文件,因此RARP服务器的功能就由用户进程来提供,而不是和TCP/IP一样由内核去实现。
  • RARP服务器实现的一个复杂因素是RARP请求是在硬件层上进行广播的。这意味着它们不经过路由器进行转发。为了让无盘系统在RARP服务器关机的状态下也能引导,通常在一个网络上(例如一根电缆)要提供多个RARP服务器,这也加大了维护成本以及网络流量。
  • RARP请求是作为一个特殊类型的以太网数据帧来传送的,不同的系统会有不同的实现。
ICMP/因特网控制报文协议

ICMP 通常被认为是ip的附属协议,尽管他们是同一层的。

tcpip详解书籍目录(吐血整理TCPIP)(6)

icmp数据包会有一个ip的首部,然后才是icmp的报文

tcpip详解书籍目录(吐血整理TCPIP)(7)

左边是icmp报文的格式

ICMP 分为差错报文和查询报文,如下图

tcpip详解书籍目录(吐血整理TCPIP)(8)

下面各种情况都不会导致产生ICMP差错报文:

  1. ICMP差错报文(但是,ICMP查询报文可能会产生ICMP差错报文)。
  2. 目的地址是广播地址(见图3-9)或多播地址(D类地址,见图1-5)的IP数据报。
  3. 作为链路层广播的数据报。
  4. 不是IP分片的第一片(将在11.5节介绍分片)。
  5. 源地址不是单个主机的数据报。这就是说,源地址不能为零地址、环回地址、广播地址或多播地址。

这些规则是为了防止过去允许ICMP差错报文对广播分组响应所带来的广播风暴。

icmp 其他用途

ICMP地址掩码请求用于无盘系统在引导过程中获取自己的子网掩码.

ICMP时间戳请求允许系统向另一个系统查询当前的时间。返回的建议值是自午夜开始计算的毫秒数.

icmp和UDP

UDP的规则之一是,如果收到一份UDP数据报而目的端口与某个正在使用的进程不相符,那么UDP返回一个ICMP不可达报文。注意,ICMP报文是在主机之间交换的,而不用目的端口号,而每个20字节的UDP数据报则是从一个特定端口(2924)发送到另一个特定端口(8888)。

ping 和 traceroute

ping he traceroute 都是基于icmp实现的应用程序。

ping 是利用 icmp的Echo Reply——回显应答)。即发送type code=80 的icmp包也称echo request,对方接受到了就要回复类型 typecode 00的icmp包,也就是echo reply。

traceroute 思路: 利用 ip数据包中的ttl,使得网关在接收到ip包时,因为ttl将变为0,因此网关会丢弃此ip包并返回icmp的的ttl超时错误。这说明,此时ip包没有达到目标地址。如果一段时间内没有收到TTL超时错误,traceroute会通过向目标主机的一个巨大的明显无法达到的端口发送数据包,如果收到了 端口不可达的回复,说明此时 包确实到了目的地。这样一躺下来就知道了到目的主机之间的所有路由。

例如:

主机A 向主机Z发送数据包。

1 . 先送出一个TTL=1的包,下一跳路由B收到后TTL会减一变为0,TTL为0时路由器B将丢弃这个数据包并回复一个TTL超时的icmp包。

  1. 此时 主机A收到了 B的回复,知道 B肯定不是目的地。于是它再发一个TTL=2的数据包给目的地Z,经过路由器B后到了C手里时,正好TTL也为0,于是C又发一个TTL超时的icmp包。
  2. 此时主机A 收到了 C回复的icmp包,说明C也没到目的地。于是它再把TTL加一,现在发一个TTL=3的数据包。。。
  3. 最终,直到不会收到ICMP 的TTL超时回复。这说明包很有可能已经到了目的地。为了确认,它使用UDP向目标主机的一个明显无法到达巨大的端口号发送数据包,到了目的地后,目的主机Z会回复 端口不可达。
  4. 收到端口不可打后,主机A就可以确定包确实到了目的地,这样也就确定了AZ之间经过的路由了。

注意:一般来说,收到的数据包的TTL不会为0,但是的确会出现。如果路由器收到了了TTL=0的数据包,会进行TTL-1,最终得到的TTL为255(因为TTL字段是8位的),然后TTL会以255开始继续在网络上传播。

RTT: 往返时延

IP选路

选路是IP最重要的功能之一。是IP层处理过程的简单流程。需要进行选路的数据报可以由本地主机产生,也可以由其他主机产生。在后一种情况下,主机必须配置成一个路由器,否则通过网络接口接收到的数据报,如果目的地址不是本机就要被直接丢弃。(悄无声息)

1. 路由表

路由操作对于运行TCP/IP的系统来说是最基本的,不管是主机还是路由器。路由表项的内容很简单,包括:5bit标志、目的IP地址(主机、网络或默认)、下一站路由器的IP地址(间接路由)或者本地接口的IP地址(直接路由)及指向本地接口的指针。主机表项比网络表项具有更高的优先级,而网络表项比默认项具有更高的优先级。

tcpip详解书籍目录(吐血整理TCPIP)(9)

  1. U 该路由可以使用。
  2. G 该路由是到一个网关(路由器)。如果没有设置该标志,说明目的地是直接相连的。
  3. H 该路由是到一个主机,也就是说,目的地址是一个完整的主机地址。如果没有设置该标志,说明该路由是到一个网络,而目的地址是一个网络地址:一个网络号,或者网络号与子网号的组合。
  4. D 该路由是由重定向报文创建的。
  5. M 该路由已被重定向报文修改。

标志G是非常重要的,因为由它区分了间接路由和直接路由(直接路不设置标志G)。

其区别在于,发往直接路由的分组中不但具有指明目的端的IP地址,还具有其链路层地址。当分组被发往一个间接路由时,IP地址指明的是最终的目的地,但是链路层地址指明的是网关(即下一站路由器).

路由匹配规则

先精准匹配表项,寻找和目标ip所在网络相同的网络地址。

如果找不到,则会使用默认路由。

如果数据报是由本地主机产生的,那么就给发送该数据报的应用程序返回“主机不可达差错”或“网络不可达差错”。如果是被转发的数据报,就给原始发送端发送一份ICMP主机不可达的差错报文。

icmp 重定向差错

当IP数据报应该被发送到另一个路由器时,收到数据报的路由器就要发送ICMP重定向差错报文给IP数据报的发送端。 例如,设A为源主机,B,C为网关/路由器,A经过 B发往C ,B发现A可以直接发给C,就会发起icmp重定向差错? 那么 B如何得知 A可以直接连C 呢 ?

  1. 我们假定主机发送一份IP数据报给R1。这种选路决策经常发生,因为R1是该主机的默认路由。
  2. R1收到数据报并且检查它的路由表,发现R2是发送该数据报的下一站。当它把数据报发送给R2时,R1检测到它正在发送的接口与数据报到达接口是相同的(即主机和两个路由器所在的LAN)。这样就给路由器发送重定向报文给原始发送端提供了线索。
  3. R1发送一份ICMP重定向报文给主机,告诉它以后把数据报发送给R2而不是R1。

tcpip详解书籍目录(吐血整理TCPIP)(10)

上面的例子和图片是卷一的原文,我的理解是(以ABC为例),B发数据给R2时,发现数据也正从同一网络接口流入。也就是说,BC作为网关在同一个子网,那么A也可以直接发给C,又因为B是A的默认路由,那么其实ABC在同一个子网内。

重定向差错的作用是在 主机没有完善的路由表时,可以通过重定向差错逐步建立起 完善的路由表

系统产生的或转发的每份IP数据报都要搜索路由表,它可以被路由守护程序或ICMP重定向报文修改。系统在默认情况下不转发数据报,除非进行特殊的配置。用route命令可以进入静态路由,可以利用新ICMP路由器发现报文来初始化默认表项,并进行动态修改。主机在启动时只有一个简单的路由表,它可以被来自默认路由器的ICMP重定向报文动态修改。

icmp 路由发现

在主机引导的时候,一般会发送在网内广播一个路由请求的ICMP报文,而路由器则会回应一个路由通告报文。此外,路由器本身不定期的在网络内发布路由通告报文。根据这些报文,主机可以建立并完善路由表。路由器在一份通告报文中可以通告多个地址,并且给出每一个地址的优先等级,这个优先等级是该IP作为默认路由的等级,至于怎么算的就不深究了。

路由器一般会在450-600秒的时间间隔内发布一次通告,而一个给定的通告报文的寿命是30分钟。而主机在引导的时候会每三秒发送一次请求报文,一旦接受到一个有效的通告报文,就停止发送请求报文。

ip选路 流程图

这张图是我自己根据理解的TCP/IP 协议 所画的,如有不合理的地方请帮忙指出。

tcpip详解书籍目录(吐血整理TCPIP)(11)

UDP /用户数据报协议首部

UDP是一个简单的面向数据报的无连接、不可靠的运输层协议。其工作原理只是简单的把应用程序发过来的包打上UDP自己8个字节的头部,并不考虑这个包的大小,然后直接扔给ip协议处理,由ip在包过大时进行分片等操作。

tcpip详解书籍目录(吐血整理TCPIP)(12)

tcpip详解书籍目录(吐血整理TCPIP)(13)

左图为封装格式,右图为 UDP的首部。 首部总共6字节。

UDP和TCP在首部中都有覆盖它们首部和数据的检验和。但是IP首部的检验和只覆盖IP的首部—并不覆盖IP数据报中的任何数据。

UDP数据报的特点

首先,UDP数据报的长度可以为奇数字节,但是检验和算法是把若干个16 bit字相加。解决方法是必要时在最后增加填充字节0,这只是为了检验和的计算(也就是说,可能增加的填充字节不被传送)。

其次,UDP数据报和TCP段都包含一个12字节长的伪首部,它是为了计算检验和而设置的。伪首部包含IP首部一些字段。其目的是让UDP两次检查数据是否已经正确到达目的地(例如,IP没有接受地址不是本主机的数据报,以及IP没有把应传给另一高层的数据报传给UDP)。UDP数据报中的伪首部格式如下图

tcpip详解书籍目录(吐血整理TCPIP)(14)

如果接收端检测到检验和有差错,那么UDP数据报就会被悄悄地丢弃,不产生任何差错报文(当IP层检测到IP首部检验和有差错时也这样做)。

UDP检验和是一个端到端的检验和。它由发送端计算,然后由接收端验证。其目的是为了发现UDP首部和数据在发送端到接收端之间发生的任何改动。

  • UDP检验和是可选的

Host Requirements RFC 声明,UDP检验和选项在默认条件下是打开的。它还声明,如果发送端已经计算了检验和,那么接收端必须检验接收到的检验和(如接收到检验和不为0)。但是,许多系统没有遵守这一点,只是在出口检验和选项被打开时才验证接收到的检验和。

IP分片

物理网络层一般要限制每次发送数据帧的最大长度。任何时候IP层接收到一份要发送的IP数据报时,它要判断向本地哪个接口发送数据(选路),并查询该接口获得其MTU。IP把MTU与数据报长度进行比较,如果需要则进行分片。分片可以发生在原始发送端主机上,也可以发生在中间路由器上。

  • 组装和再分片

把一份IP数据报分片以后,只有到达目的地才进行重新组装。重新组装由目的端的IP层来完成,其目的是使分片和重新组装过程对运输层(TCP和UDP)是透明的,除了某些可能的越级操作外。已经分片过的数据报有可能会再次进行分片(可能不止一次)。IP首部中包含的数据为分片和重新组装提供了足够的信息。

  • 分片是可选的

标志字段中有一个比特称作“不分片”位。如果将这一比特置1,IP将不对数据报进行分片。相反把数据报丢弃并发送一个ICMP差错报文(“需要进行分片但设置了不分片比特”,大多数从Berkeley派生的实现从不产生该差错)

  • 分片之间是独立的

当IP数据报被分片后,每一片都成为一个分组,具有自己的IP首部,并在选择路由时与其他分组独立。这样,当数据报的这些片到达目的端时有可能会失序,但是在IP首部中有足够的信息让接收端能正确组装这些数据报片。

  • 分片的缺陷

IP分片过程看起来是透明的,但有一个严重的缺陷:即使只丢失一片数据也要重传整个数据报。因为IP层本身没有超时重传的机制——由更高层来负责超时和重传(TCP有超时和重传机制,但UDP没有。一些UDP应用程序本身也执行超时和重传)。对于TCP而言,当来自TCP报文段的某一片丢失后,TCP在超时后会重发整个TCP报文段,该报文段对应于一份IP数据报。没有办法只重传数据报中的一个数据报片。

广播组播(多播)单播

向网络内所有/特定分组(特定多个)/一个 主机 发送数据包

广播是将数据报发送到网络中的所有主机(通常是本地相连的网络),而多播是将数据报发送到网络的一个主机组。广播和多播区别在于当收到送往上一个协议栈的数据帧时采用不同类型的过滤。每个协议层均可以因为不同的理由丢弃数据报。

目前有四种类型的广播地址:受限的广播、指向网络的广播、指向子网的广播和指向所有子网的广播。最常用的是指向子网的广播。受限的广播通常只在系统初始启动时才会发生。

广播的含义是对网络上所有的主机发送包,因此其实也包括自己。在实现中,主机发送广播包时会给自己的环回口抄送一份。

广播会不会增加网络通信量?

广播本身不会增加网络通信量,但它增加了额外的主机处理时间。如果接收主机不正确地响应了诸如ICMP端口不可达之类的差错,那么广播也可能导致额外的网络通信量。

IGMP:Internet组管理协议

IGMP 用于支持主机和路由器进行多播。它让一个物理网络上的所有系统知道主机当前所在的多播组。多播路由器需要这些信息以便知道多播数据报应该向哪些接口转发。

正如ICMP一样,IGMP也被当作IP层的一部分。IGMP报文通过IP数据报进行传输。不像我们已经见到的其他协议,IGMP有固定的报文长度,没有可选数据。

tcpip详解书籍目录(吐血整理TCPIP)(15)

tcpip详解书籍目录(吐血整理TCPIP)(16)

,