struct iphdr中的__LITTLE_ENDIAN_BITFIELD和__BIG_ENDIAN_BITFIELD
2017-04-25 20:20 tlnshuju 阅读(844) 评论(0) 收藏 举报__LITTLE_ENDIAN_BITFIELD表示小端序,__BIG_ENDIAN_BITFIELD表示大端序。
/usr/include/linux/ip.h中有一段代码定义了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;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};这里的:4是C语言中的位域。是指取二进制中的低四位(在大端序中这个低四位是存储在高地址的)。
假设使用者仅仅同意直接对ihl或者version成员,那么这一段代码能够不用推断是大端序或者小端序。
但使用者可能使用memcpy来直接对这开头的8位进行赋值操作。而在大端序和小端序的机器上会产生不同的情况。
比方以下这段代码:
u_int16_t x = 0x1; u_int8_t xx[2]; memcpy(xx, x);
在小端序的机器上结果应该是
x[0] x[1]
---------
10 .. 00
而在大端序的机器上结果则是
x[0] x[1]
---------
00 .. 01
注意x[1]的地址都是比x[0]高的。
因此为了提高兼容性(程序能够被小端序和大端序的机器共用)。须要预先推断是大端序还是小端序。并调换ihr和version在内存中的位置。
浙公网安备 33010602011771号