90-IP 协议(基础)

本章开始讲解 ICMP 协议,通过学习 ICMP 协议,我们可以顺便掌握 Raw Sockets,中译名为原始套接字。在学习 ICMP 前,还需要简单的了解一下 IP 协议。

IP 协议是 TCP/IP 协议族中最核心的协议,TCP、UDP、ICMP 等众多协议需要依赖它工作。

1. IP 首部

1.1 IP 首部格式


这里写图片描述
图1 IP 首部

IP 首部相比 TCP 首部要简单的多。因为 TCP 是可靠协议,所以需要更多的字段。

1.2 IP 首部结构体

该结构体定义在 netinet/ip.h 中。不过为了方便学习,我将该结构体定义在了 unp/include/ip.h,写程序的时候,只要引用该头文件即可。

需要注意该结构体中所有数据都是网络字节序。另一方面,需要注意大小端机器中有些字段摆放的位置是不一样的。结构体中用宏定义 __BYTE_ORDER 的值来判断。比如在小端机器中,第一个字节的高 4 位表示的是版本号,低 4 位表示的是首部长度;而在大端机器中恰好相反。

结构体中有些成员后面有一个冒号,后面跟着数字,相关知识请搜索“位域”,本文就不讲解了。

// IP首部数据结构 // 都是网络字节序 struct ip{    // 主机字节序判断 #if __BYTE_ORDER == __LITTLE_ENDIAN   uint8_t ip_hl:4;        // 首部长度   uint8_t ip_v:4;     // 版本       #endif #if __BYTE_ORDER == __BIG_ENDIAN   uint8_t ip_v:4;    uint8_t ip_hl:4;              #endif   uint8_t ip_tos;             // 服务类型   uint16_t ip_len;             // 总长度   uint16_t ip_id;                // 标识符   uint16_t ip_off;            // 标志和片偏移   uint8_t ip_ttl;            // 生存时间   uint8_t ip_p;       // 协议   uint16_t ip_sum;       // 校验和   struct in_addr ip_src;    // 32位源ip地址   struct in_addr ip_dst;   // 32位目的ip地址   // 可选项、数组起始部分 };

2. 字段解释

4 位版本号
目前协议版本号是 4,即 IPv4.
4 位首部长度
它的单位是 4 字节。比如如果首部长度是 0x05,则首部长度就是 20 字节。
服务类型(TOS)
不同的应用程序,可能有不能的需求,有的需要大呑吐量,有的要低时延,有的要可靠性高等等,该字段可以设置不同的值,来满足不同应用程序的需求。如今,大多数 TCP/IP 协议都不使用该字段了,将其设置为 0.
总长度字段
单位是 1 字节。利用总长度字段和首部长度,可以计算出 IP 数据报中内容的起始位置和长度(总长度减首部长度)。因为该字段为 16 bit,这意味着 IP 数据报总长度可以达到 65535 字节。
标识字段

该字段能够唯一标识主机发送的每一个完整的数据报。所谓一个完整的数据报,是指两种情况:

  • 如果 IP 数据报不分片,它本身就是完整的
  • 如果 IP 数据报被分片,则所有标识号相同的数据报可以组装成一个完整的数据报。
3 位标识

这三个标志位分别是:

  • RF (Reservd Fragment,保留位,总是为 0)
  • DF (Do Not Fragment,不分片,没有分片)
  • MF (More Fragment,还有更多分片)
TTL 字段
该字段表示该数据报最多可以经过多少路由器。当该字段为 0 时,数据报就被丢弃。
首部检验和
只计算 IP 首部的检验和,该算法名为二进制反码和(ones-complement sum)。为了计算一份数据报的 IP 检验和,首先把检验和字段设置成 0,然后对首部每 16 bit 进行二进制反码求和。
8 位协议

表示 IP 数据报的数据部分承载的是什么协议。比如该值为 6 时,则 IP 数据报承载 TCP 协议,如果是 17,则承载 UDP 协议,如果是 1,则承载 ICMP 协议。

回忆 socket 函数的第三个参数 —— protocol,在创建 IP 数据报时,内核会将该值填入到 8 位协议字段或者该套接字只接收 protocol 协议的 IP 数据报。

你可以在 netinet/in.h 文件中找到所有协议代号。

源 IP 地址和目的 IP 地址
每一个 IP 数据报都包含这两个字段,它标识了发送者和接收者的 IP 地址。
可选项

该选项可以不存在。如果有的话,通常有下面几种:

  • 安全和处理限制
  • 记录路径
  • 时间戳
  • 宽松的源站路由
  • 严格的源站路由

3. 总结

  • 掌握 IP 首部各个字段

说明:本文转自blog.csdn.net,用于学习交流分享,仅代表原文作者观点。如有疑问,请联系我们删除~