• 网络协议05 -网络层


    网络层


    网络层的数据包是由首部和数据两部分组成,其中数据很多时候都是由传输层传递下来的数据段(Segment)

    注意,一般来说网络层的数据包,最常见的是由传输层传递下来,但是有的可能只是三层协议(如ARP、IP、ICMP),或者两层协议(如CSMA/CD、PPP)等。

    以下图例就是网络层数据包的组成:

    在这里插入图片描述
    在WireShark中抓包的具体字段显示为:

    在这里插入图片描述

    协议首部字段


    接下来针对首部的每一个字段去讲解具体作用是干什么的

    版本(Version)

    占4位,代表是IPv4(0b0100)还是IPv6(0b0110)

    首部长度(Header Length)

    占4位,代表的是整个首部的长度(包含可变部分),不过首部的真实长度等于该字段的二进制乘以4。因为首部的最小长度为20字节(5x4),该字段的最小值为0b0101,而4个二进制最大值表示为0b1111,因此首部的最大长度为60字节(15x4)。那么由此可以得出,首部的可变部分最大长度为40字节(最大总长度60 - 固定长度20)

    区分服务(Differentiated Services Field)

    占8位,可以用于提高网络的服务质量(QoS,Quality of Service)。简单来说就是在网络传输过程中做一下差异化服务,例如某些传输可以优先通过等,以保证通过量、延迟等因素

    总长度(Total Length)

    占16位,代表是首部+数据部分的总长度(也就是整个IP数据包的长度),最大表示值为65535。

    但是在前面数据链层章节所了解到,数据链层帧的数据部分其实就是网络层的IP数据包,而帧的数据部分是有个最大值限制的(最大值为1500字节),如下图所示

    在这里插入图片描述
    那么当网络层的数据包超出1500之后,会怎么处理呢?这里网络层会将数据部分进行分片处理,而且每一片都会有自己的网络层首部(IP首部),然后将每一片传递给数据链路层封装成帧(有几片就封装成几个帧)。

    到这里问题又来了,数据链路层怎么知道哪几帧需要组成一个完整的网络层数据包呢(在接收方时,数据链路层需要找到对应几片,再还原成一个完整的IP数据)?那么接下来就需要用到另外几个字段(标识、标志、片偏移等)了

    标识(Identification)

    占16位,代表的是一个数据包的ID,当数据包过大进行分片时,同一个数据包的所有片的标识是一样的。该标识ID会由一个计数器专门进行管理,每发出一个数据包,ID就会+1,如果超出了最大值(65535),又会从0开始计数

    标志(Flags)

    占3位,每一位的作用以及在WireShark中表示如下:

    • 第一位(Reserved Bit):保留位,暂时没用
    • 第二位(Don’t Fragment):是否不允许分片,1代表不允许,0代表允许
    • 第三位(More Fragments):是否还有更多片,1代表不是最后一片,0代表是最后一片

    在这里插入图片描述

    片偏移(Fragment Offset)

    占13位,代表的是数据包分片后每一片的数据偏移位置,可以参考如下图例

    在这里插入图片描述
    当数据包分片后,每一片都有自己的首部,而且每片的总长度(首部+数据)不能超过1500字节。那么为了能保证接收方将这些片按顺序拼接成一个完整的数据包,就使用片偏移来处理这个问题

    在上图中,完整数据包的数据部分总长度为3800字节,然后被分成三个片,分别是1400、1400、1000字节,而片偏移字段的值实际是0、175、350,片偏移乘以8就是实际的字节偏移,这是由于首部的片偏移字段只有13字节,最多只能表示8191,而一个数据包最多是65535,是不够表示的,因此需要乘以8,那么也说明了分片后的数据包长度一定是8的倍数

    生存时间(Time To Live,TTL)

    占8位,每个路由器在转发之前会将该字段减1,一旦发现TTL减为0,路由器就会返回错误报告。该字段可以跟踪数据包经过了哪些路由器,能够解决手动设置路由表错误,路由器死循环等常见问题

    不同操作系统,默认的TTL值是不同的,因此也可以通过TTL来推测对方的操作系统

    在这里插入图片描述
    例如在终端调用 ping baidu.com 命令后:

    在这里插入图片描述
    可以看到从百度服务器到我这台电脑,TTL变成了54,因此可以推敲百度的服务器是部署在Linux上,而且百度服务器到我电脑之间经历了14个路由器

    通过tracert IP地址 或者 pathping IP地址 命令,可以跟踪数据包经过了哪些路由器

    协议(Protoco)

    占8位,表明所封装的数据是使用了什么协议

    在这里插入图片描述

    首部检验和(Header Checksum)

    占16位,将网络层的首部根据算法生成一个值,然后填充到该字段,用于检查首部是否有错误,其实跟数据链路层协议里面的FCS差不多

    Wire Shark数据包分片过程

    接下来通过一个具体的例子,在wireshark中看看数据包分片后的具体首部信息

    首先在终端中输入 ping ke.qq.com -l 4000命令,给腾讯课堂发送一个4000字节的数据包

    在这里插入图片描述

    然后打开wireshark,输入 ip.addr == 125.94.62.250将数据过滤一下

    在这里插入图片描述
    由于ping了4次,因此会发发送4个数据包,而且还会接受4个数据包,每个数据包在发送过程中被分成了三片(图中红框部分)。我们看到被框的部分,第一次和第二次wireshark误以为是IPv4协议,当第三片(也就是最后一片)发送过去的时候,wireshark就知道这三片属于一个完整数据包,而且是ICMP协议。

    那么接下来每个片单独分析

    • 第一片:
      在这里插入图片描述
      可以看到第一片的总长度是1500(首部20+数据1480)标识是61666,标志位的第3位为1(表示不是最后一片),片偏移为0(说明是第一片

    • 第二片:
      在这里插入图片描述
      可以看到第二片的总长度也是1500(首部20+数据1480),而且标识也是61666(说明跟第一片为同一数据包),标志位的第3位为1(表示不是最后一片),片偏移为1480(说明是紧接着第一片,也就是第二片

    注意,这里的片偏移是wireshark将原始片偏移字段乘以8得到的数据,也就是片偏移具体的字节数据

    • 第三片:
      在这里插入图片描述
      可以看到第三片的总长度是1068(ICMP首部8 + IP首部20 + IP数据1040),而且标识也是61666(说明为同一数据包),标志位的第3位为0(表明这是最后一片),片偏移为2960(说明是紧接着第二片,也就是第三片

    注意,当最后一片时,wireshark发现这是ICMP协议,会给该数据包加上ICMP的首部,8个字节

  • 相关阅读:
    面试:ThreadLocal
    【正点原子FPGA连载】 第七章 Verilog HDL语法 摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0
    【SIP&MRCP】freeswitch中的transfer和bridge有什么区别
    常用短信平台一览,记得收藏哦
    English语法_关系代词 - 注意事项
    【华为校招】【校招】【Java】考古问题
    TIOBE 6 月编程语言排行榜:C++ 即将超越 Java
    【9-1】实验——Neo4j实战操作
    圆锥曲线的分类
    微信小程序二维码
  • 原文地址:https://blog.csdn.net/ldszw/article/details/126243375