IP是TCP/IP协议族中最为核心的协议。所有的TCP、UDP、ICMP及IGMP数据都以IP数据报格式传输。IP的标准规范在RFC791中有明确的定义

1、IP报文格式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version|  IHL  |Type of Service|          Total Length         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |Flags|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Time to Live |    Protocol   |         Header Checksum       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Source Address                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Destination Address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

最高位在左边,记为0 bit;最低位在右边,记为31 bit。4个字节的32 bit值以下面的次序传输:首先是0~7 bit,其次8~15 bit,然后1 6~23 bit,最后是24~31 bit。这种传输次序称作big endian字节序。由于TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序,因此它又称作网络字节序。以其他形式存储二进制整数的机器,如little endian格式,则必须在传输数据之前把首部转换成网络字节序。这样才能保证无论是大端序还是小端序机器间能正常通信。

  • Version:协议的版本号有IPv4,IPv6等

  • IHL:Internet Header Length是首部占32 bit字的数目,包括任何选项。由于它是一个4比特字段,因此首部最长为60个字节。普通I P数据报(没有任何选择项)字段的值是5。所以一般普通IP报文首部就是20字节大小(4 * 5)

  • Type of Service:暂不讨论,一般都不支持

  • Total Length:总长度字段是指整个IP数据报的长度,以字节为单位.利用首部长度字段和总长度字段,就可以知道IP数据报中数据内容的起始位置和长度。由于该字段长16比特,所以IP数据报最长可达65535字节。尽管可以传输一个65535字节长的数据报,但是大多数的链路层都会对它进行分片,而且主机也要求不能接收超过576字节的数据报。由于TCP会把用户数据报分成若干片,因此一般来说这个限制不会影响TCP,但对UDP的应用,如RIP,TFTP,BOOTP,DNS以及SNMP,它们通常都是限制用户数据报长度为512字节,小于576B

  • Identification:标识字段唯一地标识主机发送的每一份数据报。通常每发送一份报文它的值就会加1,对于同一分组的报文它的ID是相同的,用来帮助接收端重新组装报文

  • Flags&Fragment Offset:用于报文是否分片

1
2
3
4
5
6
7
8
9
Bit 0: reserved, must be zero
      Bit 1: (DF) 0 = May Fragment,  1 = Don't Fragment.
      Bit 2: (MF) 0 = Last Fragment, 1 = More Fragments.

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

  • Header CheckSum 首部检验和字段是根据IP首部计算的检验和码。它不对首部后面的数据进行计算。ICMP、IGMP、UDP和TCP在它们各自的首部中均含有同时覆盖首部和数据检验和码。

    计算一个IP数据报检验和的方法如下:首先把检验和字段置为0;然后对首部16个字节进行二进制反码求和,结果存在检验和字段中。当收到一份IP数据报后,同样对首部进行二进制反码求和。由于接收方在计算过程中包含了发送方存在首部中的校验和,因此,如果首部在传输过程没有任何差错,那么接收方计算结果应该为全1

  • Source Address&Destination Address :报文的源地址和目的地址

  • Options :很少用到,像源策略路由会在options放入经过的路由地址

下面的是抓到的分片的IP报文,可以对照RFC定义的报文的格式看一下

2、IP路由

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

路由表中的每一项都包含下面这些信息:

  • 目的IP地址:它既可以是一个完整的主机地址,也可以是一个网络地址,由该表目中的标志字段来指定(如下所述)。主机地址有一个非0的主机号,以指定某一特定的主机,而网络地址中的主机号为0,以指定网络中的所有主机(如以太网,令牌环网)。
  • 下一跳:路由next-hop 的IP地址,或者有直接连接的网络IP地址。下一站路由器是指一个在直接相连网络上的路由器,通过它可以转发数据报。下一跳路由器不是最终的目的,但是它可以把传送给它的数据报转发到最终目的。
  • 标志:其中一个标志指明目的I P地址是网络地址还是主机地址,另一个标志指明下一站路由器是否为真正的下一站路由器,还是一个直接相连的接口。
  • 出接口:为数据报的传输指定一个网络接口。

IP路由选择是逐跳地(hop-by-hop)进行的。从这个路由表信息可以看出, IP并不知道到达任何目的的完整路径所有的IP路由选择只为数据报传输提供下一站路由器的I P地址。它假定下一站路由器比发送数据报的主机更接近目的,而且下一站路由器与该主机是直接相连的。

IP路由选择主要完成以下这些功能:

  1. 搜索路由表,寻找能与目的IP地址完全匹配的表目(网络号和主机号都要匹配)。如果找到,则把报文发送给该表目指定的下一站路由器或直接连接的网络接口(取决于标志字段的值)。

  2. 搜索路由表,寻找能与目的网络号相匹配的表目。如果找到,则把报文发送给该表目指定的下一站路由器或直接连接的网络接口(取决于标志字段的值)。目的网络上的所有主机都可以通过这个表目来处置。例如,一个以太网上的所有主机都是通过这种表目进行寻径的。这种搜索网络的匹配方法必须考虑可能的子网掩码。关于这一点我们在下一节中进行讨论。

  3. 搜索路由表,寻找标为“默认(default)”的表目。如果找到,则把报文发送给该表目指定的下一站路由器。

3、Linux&Windows 路由表

linux主机路由表:

输出项 说明

  • Destination 目标网段或者主机
  • Gateway 网关地址,”*” 表示目标是本主机所属的网络,不需要路由
  • Genmask 网络掩码
  • Flags 标记。一些可能的标记如下:
  • U — 路由是活动的
  • H — 目标是一个主机
  • G — 路由指向网关
  • R — 恢复动态路由产生的表项
  • D — 由路由的后台程序动态地安装
  • M — 由路由的后台程序修改
  • ! — 拒绝路由
  • Metric 路由距离,到达指定网络所需的中转数(linux 内核中没有使用)
  • Ref 路由项引用次数(linux 内核中没有使用)
  • Use 此路由项被路由软件查找的次数
  • Iface 该路由表项对应的输出接口

操作系统路由表中的路由可以分为以下3种:

  1. 主机路由:主机路由是路由选择表中指向单个IP地址或主机名的路由记录。主机路由的Flags字段为H。例如,在下面的示例中,本地主机通过IP地址192.168.1.1的路由器到达IP地址为10.0.0.10的主机。
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.105 192.168.1.1 255.255.255.255 UH 0 0 0 eth0
  1. 网络路由:网络路由是代表主机可以到达的网络。网络路由的Flags字段为N。例如,在下面的示例中,本地主机将发送到网络192.19.12的数据包转发到IP地址为192.168.1.1的路由器。
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.0 192.168.1.1 255.255.255.0 UN 0 0 0 eth0
  1. 默认路由:当主机不能在路由表中查找到目标主机的IP地址或网络路由时,数据包就被发送到默认路由(默认网关)上。默认路由的Flags字段为G。例如,在下面的示例中,默认路由是IP地址为192.168.1.1的路由器。
Destination Gateway Genmask Flags Metric Ref Use Iface
default(0.0.0.0) 192.168.1.1 0.0.0.0 UG 0 0 0 eth0

windows主机路由表:

  • Active Routes: 活动的路由
  • Network destination :目的网段
  • Netmask: 子网掩码
  • Gateway: 网关,又称下一跳路由器。在发送IP数据包时,网关定义了针对特定的网络目的地址,数据包发送到的下一跳服务器。如果是本地计算机直接连接到的网络,网关通常是本地计算机对应的网络接口,但是此时接口必须和网关一致;如果是远程网络或默认路由,网关通常是本地计算机所连接到的网络上的某个服务器或路由器。
  • Interface: 接口,接口定义了针对特定的网络目的地址,本地计算机用于发送数据包的网络接口。网关必须位于 和接口相同的子网(默认网关除外),否则造成在使用此路由项时需调用其他路由项,从而可能会导致路由死锁。
  • Metric: 跳数,跳数用于指出路由的成本,通常情况下代表到达目标地址所需要经过的跳跃数量,一个跳数代表经过一个路由器。跳数越低,代表路由成本越低,优先级越高。
  • Persistent Routes: 手动配置的静态固化路由
  1. 第1条路由信息:缺省路由(也即默认路由)当系统接收到一个目的地址不在路由表中的数据包时,系统会将该数据包通过192.168.1.100这个接口发送到缺省网关192.168.1.1。
  2. 第2~3条路由信息:本地环回路由。当系统接收到一个发往目标网段127.0.0.0的数据包时,系统将接收发送给该网段的所有数据包。
  3. 第5、8、11条路由信息:直连网段的路由记录。当系统接收到一个发往目的网段192.168.x.0/24的数据包时,系统会将该数据包通过192.168.x.x这个接口发送出去。
  4. 第6、9、12条路由信息:本地主机路由。当系统接收到一个目标ip地址为本地网卡ip地址的数据包时,系统会将该数据包收下。
  5. 第7、10、13条路由信息:本地广播路由。当系统接收到一个发给直连网段的本地广播数据包时,系统会将该数据包从192.168.x.x这个接口以广播的形式发送出去。
  6. 第14~17条路由信息:组播路由。当系统接收到一个组播数据包时,系统会将该数据包从127.0.0.1/192.168.x.x这个接口以组播的形式发送出去。
  7. 第18~21条路由信息:广播路由。在系统接收到一个绝对广播数据包时,系统会将该数据包通过127.0.0.1/192.168.x.x这个接口发送出去。