问题描述
当我在 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 之前。
解决方法
理解这一点的一种方法是引用 IP 标头,这里是 a link 到一个 ip 标头。
ihl
字段是 IP 头的第一个字段,因此在读取 IP 头时需要先读取它:
- Big endian:首先存储最高有效字节(即
ihl
)。因此,逻辑上ihl
字段将首先定义,以便它可以首先存储在内存中 - Little endian:首先存储最低有效字节(即
version
)。因此,version
字段将在ihl
之前定义。