首页 > 解决方案 > 无法理解 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. */
};

我只想知道为什么ihl出现在version之前。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之前。

标签: clinuxipstructureendianness

解决方案


理解这一点的一种方法是参考 IP 标头,这里是ip 标头的链接

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

  • 大端:首先ihl存储最高有效字节(即 )。因此从逻辑上讲,该ihl字段将首先被定义,因此它可以首先存储在内存中
  • 小端:首先存储最低有效字节(即version)。因此version字段将在之前定义ihl

推荐阅读