【以太网数据结构】IP协议
2015-10-12 21:14
232 查看
IP协议数据包格式:
IP协议最终目的是把数据从源传送到目的地,它不保证数据传送的靠性性!
主要作用:
数据传送:将数据从一个主机传到另一个主机
寻址:根据子网划分IP地址,发现正确的目的主机地址
路由选择:选择数据在互联网上的传送路径
数据报文的分段:当传送的数据大于MTU时,将数据进行分段发送和接收并组装
协议字段解释:
版本:IP协议版本号,长度为4位。对于IPV4,此处值为4;对于IPV6为6。
首部长度:4位,代表IP头部长度,该值 x 4 = 首部占用字节数。
服务类型:8位,该字段现在基本没什么作用,通常设为0x00。
总长度:16位(IP报文最大数据长度为65535字节),表示以字节为单位的数据报文长度,长度包含IP的头部和数据部分。
标识和片偏移:IP每发送一份数据报文后都会将此值+1。当一份报文数据大于MTU(最大传输单元,一般为1500)时就会进行分片,所分的片用片偏移记录,以便重组,由于这些分片属于同一份IP数据,故标识相同,片偏移不同。
现在TCP协议传输数据时会将数据分段,分的段足够小(一般<=1460),以至于数据到达IP层封装的时候不足以让IP分片,知道为什么会这样吗?
因为IP协议不保证数据传送的靠性性!当一份IP数据的某个小分片丢失时(事实上数据包丢失的情况非常常见),整个IP报文都得重传!!!TCP协议事先在三次握手的过程中协商了MSS值(最大TCP分段大小),将设置MSS值小于等于1460,这样大大降低了数据重传所付出的代价。
生存时间TTL:8位,该字段的值表示数据报文组多可以经过的路由器的数量。该字段很有意思,每经过一个路由器,TTL的值会减1,当TTL的值为0时,路由器会将该数据包丢弃,以防止该包在网络中不断循环,当然路由器丢弃该数据包时会发送一个ICMP报文通知源主机。
协议类型:8位,表示IP上承载的是什么协议,见下表:
头部校验和:16位,只对IP头部进行校验。接收方接收到数据后也会对数据进行校验,然后和该字段进行比对,如果不匹配则表示此帧数据发生错误。由于数据每经过一个路由器都会更改TTL值,所以路由器要重新对IP包头进行校验。
源地址和目的地址:分别表示发送数据的主机和接收数据的主机的IP地址。
IP选项:该字段一般为空,很少用到,不解释。
相关源代码
再linux/ip.h文件中,ip包头结构体定义如下:
获取ip包头结构体函数:
IP协议最终目的是把数据从源传送到目的地,它不保证数据传送的靠性性!
主要作用:
数据传送:将数据从一个主机传到另一个主机
寻址:根据子网划分IP地址,发现正确的目的主机地址
路由选择:选择数据在互联网上的传送路径
数据报文的分段:当传送的数据大于MTU时,将数据进行分段发送和接收并组装
协议字段解释:
版本:IP协议版本号,长度为4位。对于IPV4,此处值为4;对于IPV6为6。
首部长度:4位,代表IP头部长度,该值 x 4 = 首部占用字节数。
服务类型:8位,该字段现在基本没什么作用,通常设为0x00。
总长度:16位(IP报文最大数据长度为65535字节),表示以字节为单位的数据报文长度,长度包含IP的头部和数据部分。
标识和片偏移:IP每发送一份数据报文后都会将此值+1。当一份报文数据大于MTU(最大传输单元,一般为1500)时就会进行分片,所分的片用片偏移记录,以便重组,由于这些分片属于同一份IP数据,故标识相同,片偏移不同。
现在TCP协议传输数据时会将数据分段,分的段足够小(一般<=1460),以至于数据到达IP层封装的时候不足以让IP分片,知道为什么会这样吗?
因为IP协议不保证数据传送的靠性性!当一份IP数据的某个小分片丢失时(事实上数据包丢失的情况非常常见),整个IP报文都得重传!!!TCP协议事先在三次握手的过程中协商了MSS值(最大TCP分段大小),将设置MSS值小于等于1460,这样大大降低了数据重传所付出的代价。
生存时间TTL:8位,该字段的值表示数据报文组多可以经过的路由器的数量。该字段很有意思,每经过一个路由器,TTL的值会减1,当TTL的值为0时,路由器会将该数据包丢弃,以防止该包在网络中不断循环,当然路由器丢弃该数据包时会发送一个ICMP报文通知源主机。
协议类型:8位,表示IP上承载的是什么协议,见下表:
值 | 协议类型 | 值 | 协议类型 |
---|---|---|---|
1 | ICMP | 6 | TCP |
2 | IGMP | 17 | UDP |
源地址和目的地址:分别表示发送数据的主机和接收数据的主机的IP地址。
IP选项:该字段一般为空,很少用到,不解释。
相关源代码
再linux/ip.h文件中,ip包头结构体定义如下:
[code]struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, version:4; #elif defined (__BIG_ENDIAN_BITFIELD) __u8 version:4, ihl:4; #else #error "Please fix <asm/byteorder.h>" #endif __u8 tos; __be16 tot_len; __be16 id; __be16 frag_off; __u8 ttl; __u8 protocol; __sum16 check; __be32 saddr; __be32 daddr; /*The options start here. */ };
获取ip包头结构体函数:
[code]#ifdef __KERNEL__ #include <linux/skbuff.h> static inline struct iphdr *ip_hdr(const struct sk_buff *skb)//常用 { return (struct iphdr *)skb_network_header(skb); } static inline struct iphdr *ipip_hdr(const struct sk_buff *skb) //TCP头,在数据包未拆封之前,sk_buff结构体成员TCP头指针可能和IP头指针指向同一个位置 { return (struct iphdr *)skb_transport_header(skb); } #endif
相关文章推荐
- 数据结构之-线性表
- 【ShancoLove】带你看数据结构——第四课:线性表链式结构(循环链表)
- 【读书笔记】大话数据结构之 栈(1)
- 二叉树-遍历
- 二叉树-层序遍历
- 二叉树-非递归遍历(先、中、后)
- 链队
- 循环队列(顺序队列)
- 后缀表达式求值(顺序栈)
- 迷宫问题(顺序栈)
- 数制转换问题(顺序栈)
- 单链表求集合交并
- 单链表的逆置
- 数据结构之链表A分解为结点小于零的链表B、结点大于零的链表C
- [数据结构]字符串匹配(KMP方法)
- 第四周【项目6-1 - 多项式求和】 数据结构实践——链表:
- 数据结构实践—— 负数把正数赶出队列
- 【队列项目1 - 建立顺序环形队列算法库——第6周】
- 项目6 -- 停车场模拟
- 2015-10-12 【项目3 - 括号的匹配】