无法理解 ip 结构实现

问题描述

当我在 C 中试验结构概念时,我正在检查 IP 标头是如何实现的,所以我在互联网上找到了以下声明。

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;
    __u16   tot_len;
    __u16   id;
    __u16   frag_off;
    __u8    ttl;
    __u8    protocol;
    __u16   check;
    __u32   saddr;
    __u32   daddr;
    /*The options start here. */
};

我只想知道在小端的情况下为什么 ihlversion 之前出现。 wrt little endian,最低有效位将存储在较低的内存位置在这种情况下,可以首先定义版本,为什么在ihl之后定义它。

我已经完成了下面的expt,请帮助我理解。

#include<stdio.h>

struct my_iphdr {
    unsigned char ver:4;
    unsigned char ihl:4;
};

int main(void)
{
    struct my_iphdr ip;
    ip.ver = 0;
    ip.ihl = 15;

    char * ptr = &ip;

    printf("%d\n",(unsigned char)*ptr);

    return 0;
} 

我使用的是小端机器

Architecture:        x86_64
cpu op-mode(s):      32-bit,64-bit
Byte Order:          Little Endian
cpu(s):              12

我有 o/p 240 即 11110000 在这种情况下,ver 存储在较低位,在取消引用后,我能够看到正确的值,那么为什么 ihl > 出现在 ver 之前。

解决方法

理解这一点的一种方法是引用 IP 标头,这里是 a link 到一个 ip 标头。

ihl 字段是 IP 头的第一个字段,因此在读取 IP 头时需要先读取它:

  • Big endian:首先存储最高有效字节(即 ihl)。因此,逻辑上 ihl 字段将首先定义,以便它可以首先存储在内存中
  • Little endian:首先存储最低有效字节(即 version)。因此,version 字段将在 ihl 之前定义。