IP数据报报文中的头部格式设置

在进行网络编程时,需要自己来设置一个IP报文,然后再发送到网卡上,以下资料是我在查看了多人文章整理得到。

这里写图片描述

版本(Version):它标识了数据包IP版本号。4位字段的值设置为二进制的0100表示IP版本4(IPv4).设置为0110表示IP版本6(IPv6)。

首部长度:占4位。即从0000~~~~1111,可表示的最大十进制数字是15。首部长度的单位是(32位,即4字节),即当“首部长度”表示为0001时,指首部的长度是1个4字节,那么,通过“首部长度”这个字段可以看出,真正的首部的长度应该是0~15(4字节),即0~60字节。首部的固定长度为20个字节,“首部长度”为“0101(5)”是最常用的,此时只有固定部分,没有任何选项(可变部分)。

服务类型:字段长度为8位,它用来指定特殊的数据包处理方式。服务类型字段实际上被划分为:3bit的优先权和4bit的Tos子字段1bit的未用位置,其中1bit未用位必须置0。优先权用来设置数据包的优先级。Tos允许按照吞吐量、时延、可靠性和费用方式选择传输服务。4bit的TOS分别代表:最小时延,最大吞吐量,最高可靠性和最小费用。4bit中只能置其中1比特。如果所有4bit均为0,那么就意味着是一般服务。

这里写图片描述

       IP优先级部分共三位,取值范围为0~7(值越大,优先级越高)。用名称表示时,这8个取值分别为routine(普通,值为000)、priority(优先,值为001)、immediate(快速,值为010)、flash(闪速,值为011)、flash-override(急速,值为100)、critical(关键,值为101)、internetwork control (网间控制,值为110)和network control(网络控制,值为111),分别对应于数字0~7。
       虽然ToS部分共有四位,但每个IP包中这四位中只能有一位为1,所以实际只有五个取值(包括全为0的值)。这五个值所对应的名称和数值分别为:normal(一般服务,取值为0000)、min-monetary-cost(最小开销,取值为0001,确保路径开销最小)、max-reliability(最高可靠性,0010,确保可靠性最高)、max-throughput(最大吞吐量,取值为0100,确保传输速率最高)、min-delay(最小时延,取值为1000,确保传输延时最小)。

总长度:总长度字段是指IP数据报的长度,分片后的每一个分片的报头长度和数据长度之和。以字节为单位。这里的单位为字节,而不是4字节。 由于该字段长16bit,所以IP数据报最长可达65535字节。当数据报被分片时,该字段的值也随着变化。

标识:唯一的标识主机发送的每一份数据报的标志。IP软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并赋给标识字段。当数据报进行分片处理后,每个分片的标识值都与原数据报的标识值相同,则在接收端具有相同标识值的分片就能最终正确的重装成为原来的数据报。

标志:共3位。R、DF、MF三位。目前只有后两位有效,

0比特(R):保留,必须为0;
1比特(DF):=0,可以分片;=1,不可以分片;
2比特(MF)=0,最后的分片;=1,还有更多的分片;

片偏移:占13比特。表示该IP包在该组分片包中位置,接收端靠此来组装还原IP包。

生存时间:占8比特。用来设置数据报最多可以经过的路由器数。由发送数据的源主机设置,通常为32、64、128等。每经过一个路由器,其值减1。当TTL值减为0时,路由器将丢弃数据报,并向源端发送一个ICMP差错报文。TTL值可以防止数据报陷入路由循环。发送 ICMP 回显应答时经常把 TTL 设为最大值 255。

协议字段:占8比特。指明IP层所封装的上层协议类型(传输层),如ICMP(1)、IGMP(2) 、TCP(6)、UDP(17) IDRP(88)、OSPF(89)等。

首部校验和: 占16bit,该字段只校验IP数据报的报头,但不包括数据部分。
校验和采用十六进制反码求和,IP首部校验和的计算主要是两步:按位异或和取反。


对于发送方计算检验和:
  1. 初始计算校验和字段时该字段全部用0填充;

  2. IP头部以16位为一个单位,逐个模2加(相当于异或);

  3. 得到的结果取反,作为校验和放入校验和字段;
对于接收者来说,验证也很简单:
 1. 对于接收的IP报文头部以16位为单位逐个求和;

 2. 若结果为1,则校验正确,否则出错丢弃;

代码如下:

static WORD CalculateCheckSum(const BYTE *pdata, int length)
    {
        WORD *ptemp=(WORD *)pdata;
        DWORD temp=0;
        for (int i=0; i<length/2; i++)
        {
            temp += *ptemp++;
        }
        return ~((WORD)((temp&0xFFFF)+(temp>>16)));
    }

源IP地址、目标IP地址字段:各占32比特。用来标明发送IP数据报文的源主机地址和接收IP报文的目标主机地址。

可选项字段:占32比特。用来定义一些任选项:如记录路径、时间戳等。这些选项很少被使用,同时并不是所有主机和路由器都支持这些选项。可选项字段的长度必须是32比特的整数倍,如果不足,必须填充0以达到此长度要求。






参考资料:

https://www.2cto.com/net/201310/252399.html
http://www.cnblogs.com/czyseu/p/4727299.html
http://blog.csdn.net/ceelo_atom/article/details/46858869
http://blog.csdn.net/smiler_sun/article/details/48396299
http://www.mamicode.com/info-detail-542445.html
https://zhangbinalan.gitbooks.io/protocol/content/ipxie_yi_tou_bu.html

猜你喜欢

转载自blog.csdn.net/ONEMOOC/article/details/78472653