【问题标题】:Having trouble understanding ip structure implementation无法理解 ip 结构的实现
【发布时间】:2021-04-21 13:18:59
【问题描述】:

当我在 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 之前。

【问题讨论】:

  • 这个人说得比我好:stackoverflow.com/questions/18070977/…希望这有帮助
  • @Farkash 感谢您的重播,这意味着很多。我的问题是,如果我们谷歌 IP 帧格式,第一个字段是版本,那么在小端的情况下,前 4 位应该是版本字段,对吗?为什么“ihl”排在第一位?在这种情况下,前 4 位将被视为 'ihl' 而不是帧格式中的版本。
  • 这能回答你的问题吗? Why bit endianness is an issue in bitfields?

标签: c linux ip structure endianness


【解决方案1】:

理解这一点的一种方法是参考 IP 标头,这里是a link 指向 IP 标头。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-19
    • 2016-06-24
    • 2014-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多