IP数据包格式网络
0 4 8 16 31ide
|4位版本 | 4位首部长度 | 8位服务类型 | 16位总长度(字节数)|测试
|16位标识 | 3位标志 | 13位片偏移 |spa
|8位生存时间| 8位协议 | 16位首部校验和 |.net
|32位源IP地址|blog
|32位目的IP地址|ip
|选项(可无)|路由
|数据|get
netinet/ip.h中定义ip:qt
struct ip
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
unsigned int ip_hl:4; /* header length */
unsigned int ip_v:4; /* version */
#endif
#if __BYTE_ORDER == __BIG_ENDIAN
unsigned int ip_v:4; /* version */
unsigned int ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
u_short ip_len; /* total length */
u_short ip_id; /* identification */
u_short ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_short ip_sum; /* checksum */
struct in_addr ip_src, ip_dst; /* source and dest address */
};
解析
12. 分片: 把一个数据报为了适合网络传输而分红多个数据报的过程称为分片,被分片后的各个IP数据报可能通过不一样的路径到达目标主机。 一个IP数据报在传输过程当中可能被分片,也可能不被分片。若是被分片,分片后的IP数据报和原来没有分片的IP数据报结构是相同的,即也是由IP头部和IP数据区两个部分组成: 分片后的IP数据报,数据区是原IP数据报数据区的一个连续部分,头部是原IP数据报头部的复制,但与原来未分片的IP数据报头部有两点主要不一样:标志和片偏移
(1)标志:在IP数据报头部有一个叫“标志”的字段,用3位二进制数表示: 不分片DF(Do not Fragment)标志若是被置1,则数据报在传输过程当中不能被分片,如网络连通性测试命令ping就能够用-F参数设置为在数据传输时不分片,但这样当数据不能经过MTU较小的网络时,将产生数据不可达的错误。 片未完MF(More Fragment)标志若是被置1,说明该数据报不是分片后的最后一个数据报,最后一个数据报的该位被置0。
(2)片偏移:IP数据报被分片后,各片数据区在原来IP数据区中的位置用13位片偏移来表示。上图中分片1的偏移为0;分片2的偏移为600;分片3的偏移为1200。实际在IP地址中,因为偏移是以8个字节为单位进行计算的,于是在IP数据报中分片1的偏移是0;分片2的偏移是75;分片3的偏移是150。
13. 重组: 当分了片的IP数据报到达最终目标主机时,目标主机对各分片进行组装,恢复成源主机发送时的IP数据报,这个过程叫作IP数据报的重组。 在IP数据报头部中,标识用16位二进制数表示,它惟一地标识主机发送的每一份数据报。在一个数据报被分片时,每一个分片仅把数据报“标识”字段的值原样复制一份,因此一个数据报的全部分片具备相同的标识。 目标端主机重组数据报的原理是:
(1)根据“标识”字段能够肯定收到的分片属于原来哪一个IP数据报;
(2)根据“标志”字段的“片未完MF”子字段能够肯定分片是否是最后一个分片;
(3)根据“偏移量”字段能够肯定分片在原数据报中的位置。
14. IP数据包的首部长度和数据包长度都是变长的,但老是4字节的整数倍。每一个IP数据包长度最大为1500字节(MTU),包首长20~60字节(选项最多40字节),因此数据长度为1480~1440字节。