IP协议协议--IP头部信息

《Linux高性能服务器编程》阅读笔记:

1. IP协议概述

  IP协议是TCP/IP协议簇的核心,它为上层(传输层)协议(TCP/UDP)提供无状态、无连接、不可靠的服务。

  (1) 无状态: IP通信双方的数据状态信息不同步,即所有的IP数据报的发送、传输、接收都是相互独立的,没有上下文关系。优点是简单高效,不占用内核结构来保存通信状态,每次传输数据时不用携带状态信息
  (2) 无连接: IP通信双方不能长久地维持对方的任何信息。上层协议每次发送数据时都需要指明通信对方的地址
  (3) 不可靠: 不能保证IP数据报准确地到达接收端,它只是承诺尽最大的努力

  在网络协议中无状态无连接是很常见的,如UDP协议和HTTP协议。HTTP协议中,一个浏览器的连续两次网页请求之间并没有关联,它们被WEB服务器独立处理。使用IP服务的上层协议若要实现数据确认、超时重传等机制,就需要在上层协议中实现,如TCP协议。

2. IPv4头部结构

  以IPv4版本的IP协议为例,分析其头部信息:
  IPv4的头部结构长度为20字节,若含有可变长的选项部分,最多60字节。
IP协议协议--IP头部信息_第1张图片

  (1) 版本号:IP协议的版本。对于IPv4来说值是4
  (2) 头部长度:4位最大为0xF,注意该字段表示单位是字(4字节)
  (3) 服务类型(Type Of Service,TOS):3位优先权字段(现已被忽略) + 4位TOS字段 + 1位保留字段(须为0)。4位TOS字段分别表示最小延时、最大吞吐量、最高可靠性、最小费用,其中最多有一个能置为1。应用程序根据实际需要来设置 TOS值,如ssh和telnet这样的登录程序需要的是最小延时的服务,文件传输ftp需要的是最大吞吐量的服务
  (4) 总长度: 指整个IP数据报的长度,单位为字节,即IP数据报的最大长度为65535字节(2的16次方)。由于MTU的限制,长度超过MTU的数据报都将被分片传输,所以实际传输的IP分片数据报的长度远远没有达到最大值

  下来的3个字段则描述如何实现分片:
  (5) 标识:唯一地标识主机发送的每一个数据报,其初始值是随机的,每发送一个数据报其值就加1。同一个数据报的所有分片都具有相同的标识值
  (6) 标志: 位1保留,位2表禁止分片(DF),若设置了此位,IP模块将不对数据报进行分片,在此情况下若IP数据报超过MTU,IP模块将丢弃数据报并返回一个ICMP差错报文;位3标识更多分片(MF),除了数据报的最后一个分片,其他分片都要把它设置为1
  (7) 位偏移:分片相对原始IP数据报数据部分的偏移。实际的偏移值为该值左移3位后得到的,所以除了最后一个IP数据报分片外,每个IP分片的数据部分的长度都必须是8的整数倍

  (8) 生存时间::数据报到达目的地之前允许经过的路由器跳数。TTL值被发送端设置,常设置为64。数据报在转发过程中每经过一个路由该值就被路由器减1.当TTL值为0时,路由器就将该数据包丢弃,并向源端发送一个ICMP差错报文。TTL可以防止数据报陷入路由循环
  (9) 协议: 区分IP协议上的上层协议。在Linux系统的/etc/protocols文件中定义了所有上层协议对应的协议字段,ICMP为1,TCP为6,UDP为17
  (10) 头部校验和: 由发送端填充接收端对其使用CRC算法校验,检查IP数据报头部在传输过程中是否损坏
  (11) 源IP地址和目的IP地址: 表示数据报的发送端和接收端。一般情况下这两个地址在整个数据报传递过程中保持不变,不论中间经过多少个路由器
  (12) 选项:可变长的可选信息,最多包含40字节。选项字段很少被使用。可用的IP可选项有:
  a. 记录路由: 记录数据包途径的所有路由的IP,这样可以追踪数据包的传递路径
  b. 时间戳: 记录每个路由器数据报被转发的时间或者时间与IP地址对,这样就可以测量途径路由之间数据报的传输的时间
  c. 松散路由选择: 指定路由器的IP地址列表数据发送过程中必须经过所有的路由器
  d. 严格路由选择: 数据包只能经过被指定的IP地址列表的路由器
  e. 上层协议(如TCP/UDP)的头部信息

3. tcpdump抓取IP数据报

  在Ubuntu 14.04中执行telnet命令登录本机,并在另一终端抓取这个过程中telnet服务器-telnet客户端之间的数据包:

$ sudo tcpdump -ntx -i lo

  在另一终端:

$ telnet 127.0.0.1

IP协议协议--IP头部信息_第2张图片

  观察tcpdump抓取到的数据:

tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
IP 127.0.0.1.44626 > 127.0.0.1.23: Flags [S], seq 3041640326, win 43690, options [mss 65495,sackOK,TS val 4701824 ecr 0,nop,wscale 7], length 0
    0x0000:  4510 003c 0106 4000 4006 3ba4 7f00 0001
    0x0010:  7f00 0001 ae52 0017 b54b bf86 0000 0000
    0x0020:  a002 aaaa fe30 0000 0204 ffd7 0402 080a
    0x0030:  0047 be80 0000 0000 0103 0307

  这是一个IP数据报:
  (1) telnet登录的是本机,所以IP数据报的源端IP地址和目的端IP地址都是127.0.0.1。telnet服务器使用的端口号是23,

telnet          23/tcp  #摘自/etc/services文件

  telnet客户端使用的是临时端口号44626。telnet服务使用的是TCP协议,Flags、sq、win、options描述的都是TCP头部信息,详细将在TCP协议分析中解析。

  (2) tcpdump命令开启-x选项,使之输出二进制码。这些二进制码用十六进制的格式呈现,共60字节: 前20字节是IP头部,后40字节是TCP头部。length为0表示这些数据不包含数据。

  对照前面表格的IPv4,可得各数据取值意义如下:

0x4             4位的版本号                      IP版本号
0x5             4位的头部长度                 头部长度为5个字(20字节)
0x10            8位的服务类型TOS              开启最小延时服务
0x003c          16位的总长度                 数据包总长度(60字节)

0x0106          16位的标识                      数据报标识
0x4             3位的标志                       禁止分片,因没携带数据

0x000           13位的位偏移                 为0表没发生位偏移
0x40            8位的生存时间                 生存时间为64跳
0x06            8位的协议字段                 为6表上层协议是TCP协议

0x3ba4          16位的IP头部校验和             头部校验和

0x7f00 0001     32位的源端IP地址              源端IP地址127.0.0.1
0x7f00 0001     32位的目的端IP地址             目的端IP地址127.0.0.1

你可能感兴趣的:(Linux系统/网络编程,Linux编程)