网络知识
RFC 精读 · Internet · STD 5

RFC 791

Internet Protocol —— 无连接数据报、20–60 字节首部、分片与 TTL。后续几乎所有样本都包在这一层外面。

编号 / 标题
RFC 791 · Internet Protocol
发布
September 1981 · ISI / J. Postel
状态
Internet Standard · STD 5(与 ICMP 同属 STD 5)
关系
Obsoletes RFC 760 · Updated by RFC 1349RFC 2474RFC 6864
原文
rfc-editor HTML · 纯文本 · datatracker
实验室样本
每条 IPv4 样本的外层;分片字段对照 ICMP/TCP/UDP

RFC 791 把 IP 定义成无连接、尽力而为的数据报服务:不保证顺序、不保证送达、不建立连接。可靠性留给 ICMP 反馈和 TCP 这类上层。ToS 字节后来被 DSCP/ECN 重画(RFC 2474),Identification 的语义也被 RFC 6864 收紧;读 791 时把图记住,再记住哪些比特被后文改写。

Field definitions

长度、标志、TTL、协议、校验和

  Total Length:  16 bits

    Total Length is the length of the datagram, measured in octets,
    including internet header and data.  This field allows the length of
    a datagram to be up to 65,535 octets.  Such long datagrams are
    impractical for most hosts and networks.  All hosts must be prepared
    to accept datagrams of up to 576 octets (whether they arrive whole
    or in fragments).  It is recommended that hosts only send datagrams
    larger than 576 octets if they have assurance that the destination
    is prepared to accept the larger datagrams.

[……节选 Identification,下接 Flags]

  Flags:  3 bits

    Various Control Flags.

      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 |
        +---+---+---+

[……节选页眉,下接 Fragment Offset / TTL / Protocol / Header Checksum]

    The fragment offset is measured in units of 8 octets (64 bits).  The
    first fragment has offset zero.

  Time to Live:  8 bits

    This field indicates the maximum time the datagram is allowed to
    remain in the internet system.  If this field contains the value
    zero, then the datagram must be destroyed.  This field is modified
    in internet header processing.  The time is measured in units of
    seconds, but since every module that processes a datagram must
    decrease the TTL by at least one even if it process the datagram in
    less than a second, the TTL must be thought of only as an upper
    bound on the time a datagram may exist.  The intention is to cause
    undeliverable datagrams to be discarded, and to bound the maximum
    datagram lifetime.

  Protocol:  8 bits

    This field indicates the next level protocol used in the data
    portion of the internet datagram.  The values for various protocols
    are specified in "Assigned Numbers" [9].

  Header Checksum:  16 bits

    A checksum on the header only.  Since some header fields change
    (e.g., time to live), this is recomputed and verified at each point
    that the internet header is processed.

注解

Total Length 含首部。576 是“所有主机必须收得下”的下限,不是以太网 MTU。以太网上常见的是 1500 字节 IP 包。

DF / MF / Offset 三件套决定分片。每片起点按 8 字节对齐;MF=1 的非末片数据长度必须是 8 的倍数,末片可以不是。DF=1 时中间路由器不得再切,只能丢并(通常)回 ICMP Type 3 Code 4——这是 PMTUD 的扳机。

TTL 名义是秒,实现上每台处理模块至少减 1,所以它是跳数上限。减到 0 丢弃,这是 traceroute 的原理。TTL 一变,首部校验和必须重算

Protocol:1=ICMP,6=TCP,17=UDP,89=OSPF。它不是端口号。

易误解:“IP 校验和保护整包”。原文写得很死:on the header only。TCP/UDP 校验和含 IPv4 伪首部;ICMPv4 校验和只覆盖 ICMP 报文本身,没有伪首部。

Fragmentation and Reassembly

谁切、谁拼、哪些字段会变

    The internet identification field (ID) is used together with the
    source and destination address, and the protocol fields, to identify
    datagram fragments for reassembly.

[……节选页眉。未分片条件见下条注解;此处从完整句开始]

If an internet datagram is fragmented, its data portion must be
    broken on 8 octet boundaries.

[……节选片数上限说明]

    Every internet module must be able to forward a datagram of 68
    octets without further fragmentation.  This is because an internet
    header may be up to 60 octets, and the minimum fragment is 8 octets.

    Every internet destination must be able to receive a datagram of 576
    octets either in one piece or in fragments to be reassembled.

    The fields which may be affected by fragmentation include:

      (1) options field
      (2) more fragments flag
      (3) fragment offset
      (4) internet header length field
      (5) total length field
      (6) header checksum

    If the Don't Fragment flag (DF) bit is set, then internet
    fragmentation of this datagram is NOT permitted, although it may be
    discarded.  This can be used to prohibit fragmentation in cases
    where the receiving host does not have sufficient resources to
    reassemble internet fragments.

注解

重组键是 (源 IP, 目的 IP, Protocol, Identification)。同一数据报的各片 ID 相同。重组发生在目的主机,中间路由器通常只转发片,不拼回去。

未分片的包:MF=0 且 Offset=0。只看 MF=0 不够——最后一片也是 MF=0,但 Offset≠0。

68 与 576 是两道不同的门槛:转发模块必须能原样转发 68 字节(最长首部 + 最小片);目的主机必须能收 576。现代网络更常见的是靠 PMTUD 避免中间分片。

RFC 6864 之后,Identification 对原子数据报(DF=1 且未分片)不再承担“唯一标识待重组报文”的旧义务。考试若问 791 原文,仍按上面四元组答。

抓包对照

Wireshark 树里的 Internet Protocol Version 4 与线上字节一一对应。过滤器 ipip.addr == …ip.flags.df == 1

ip.version == 4 ip.hdr_len IHL×4 ip.len Total Length ip.id / ip.flags.df / ip.flags.mf / ip.frag_offset ip.ttl ip.proto 1 ICMP · 6 TCP · 17 UDP ip.checksum 仅首部 ip.src / ip.dst tcpdump: ip ip[8] == 1 TTL==1(常是 traceroute 探针) ip[9] == 6 TCP 'ip[6] & 0x40 != 0' DF 'ip[6] & 0x20 != 0' MF

考点与易错点

  1. IHL 以 4 字节为单位,最小 5(20 B),最大 15(60 B)。
  2. 校验和只覆盖首部;TTL 每跳变化后必须重算。
  3. 每片起点按 8 字节对齐;MF=1 的非末片数据长度必须是 8 的倍数,末片可以不是。未分片 = MF=0 且 Offset=0。
  4. DF=1 禁止中间分片,过大则丢,常触发 ICMP Fragmentation Needed。
  5. TTL 名义是秒、实现是跳数。traceroute 靠它骗出 Time Exceeded。
  6. Protocol 是“交给谁”(1/6/17),不是端口。端口在 UDP/TCP 首部。