前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >IP协议格式

IP协议格式

作者头像
随心助手
发布2021-11-12 15:06:05
1.3K0
发布2021-11-12 15:06:05
举报
文章被收录于专栏:nginx遇上redisnginx遇上redis

一、IP协议

IP协议是TCP/IP协议族所依赖的传送机制,提供无连接不可靠的数据报服务。IP的无连接特性意味着每个IP报文都是独立寻径的,因此当一个源主机发送多个报文给同一目的主机时,这些报文可能出现错序,丢失或者部分报文产生错误等现象,因此为了保证数据传送的可靠性,必须在IP层之上通过TCP协议提供有序,带确认数据的传输服务。

1.IP协议格式

IP报文由报文头部和数据两部分构成,其中头部信息格式如下图所示,头部占20-60个字节,无选项option时,头部为20字节,最多可以携带40字节选项,报文最大长度为65535字节。

(1)版本(version) 4比特,定义了当前IP协议的版本,目前通常是数字4,即IPV4

(2)头部长度(ihl) 4比特,按4字节单位定义IP报文的头部总长度,因此未携带任何选项的IP报文头部长度为20字节,则ihl值为5(5*4=20),当选项长度达到最大值40字节时,ihl长度为15 (15*4=60)。

(3)服务类型(tos) 8比特,用于指示路由器将如何处理IP报文

(4)总长度(tot_len)16比特,报文头部加数据的总长度,IP报文携带的上层数据长度为:数据长度=总长度-头部长度=总长度-(ihl*4)。之所以需要总长度这个字段,是因为在某些情况下底层协议为了满足最小帧长的限制,会添加填充数据,例如以太协议要求每个数据帧最小必须为46字节,当来自上层的IP报文总长度小于46字节时,将添加填充数据以满足最小帧长,于是必须通过总长度这个字段来记录实际IP层报文的总长度,参考如图所示:

(5)报文标识(id) 16比特,用于标识多个IP分段所对应的原始IP分组的ID。

(6)分段标识(frag)3比特,用于声明一个IP报文是否是某个原始报文的分段,或者声明是否允许一个IP原始报文被分段。

(7)分段偏移(offset) 13比特,标识一个IP分段的数据在原始IP报文中的偏移值,注意该值,必须是8的整数倍。

(8)生存时间(ttl) 8比特, 一个IP报文在网上所允许的最大生存时间,该值实际为最大跳数,当源主机产生一个IP报文后,该字段将填写一个初始值,随后该报文每经过一个路由器则路由器将对该字段值进行减一操作,当该字段值变成0后,路由器将丢弃此报文。

(9)协议(protocol) 8比特,用于标识IP报文承载的上层数据的协议类型,例如可以是TCP,UDP,ICMP和IGMP等。

(10)头部校验和(check) 16比特,IP头部数据的检验和。

(11)源地址(saddr) 32比特,报文的源IP地址。

(12)目的地址(daddr)32比特,报文的目的IP地址。

(13)选项(option) 变长且最大不超过40字节。

c语言定义结构:

代码语言:javascript
复制
 1 struct ip {
 2 #if BYTE_ORDER == LITTLE_ENDIAN 
 3     u_char  ip_hl:4,        /* header length */
 4         ip_v:4;         /* version */
 5 #endif
 6 #if BYTE_ORDER == BIG_ENDIAN 
 7     u_char  ip_v:4,         /* version */
 8         ip_hl:4;        /* header length */
 9 #endif
10     u_char  ip_tos;         /* type of service */
11     short   ip_len;         /* total length */
12     u_short ip_id;          /* identification */
13     short   ip_off;         /* fragment offset field */
14 #define IP_DF 0x4000            /* dont fragment flag */
15 #define IP_MF 0x2000            /* more fragments flag */
16     u_char  ip_ttl;         /* time to live */
17     u_char  ip_p;           /* protocol */
18     u_short ip_sum;         /* checksum */
19     struct  in_addr ip_src,ip_dst;  /* source and dest address */
20 };
代码语言:javascript
复制
 1 struct iphdr {
 2     #if defined(__LITTLE_ENDIAN_BITFIELD)
 3         __u8    ihl:4,
 4                 version:4;
 5     #elif defined (__BIG_ENDIAN_BITFIELD)
 6         __u8    version:4,
 7                 ihl:4;
 8     #else
 9         #error  "Please fix <asm/byteorder.h>"
10     #endif
11          __u8   tos;
12          __u16  tot_len;
13          __u16  id;
14          __u16  frag_off;
15          __u8   ttl;
16          __u8   protocol;
17          __u16  check;
18          __u32  saddr;
19          __u32  daddr;
20          /*The options start here. */
21 };

看完本文有收获?请转发分享更多人

因为分享是一种美德

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 nginx遇上redis 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档