struct iphdr中的__LITTLE_ENDIAN_BITFIELD和__BIG_ENDIAN_BITFIELD

来源:互联网 发布:飞鸟淘宝客学习 编辑:程序博客网 时间:2024/05/21 21:01

__LITTLE_ENDIAN_BITFIELD表示小端序,__BIG_ENDIAN_BITFIELD表示大端序。

/usr/include/linux/ip.h中有一段代码定义了ip首部的结构体,如下:

struct iphdr {#if defined(__LITTLE_ENDIAN_BITFIELD)__u8ihl:4,version:4;#elif defined (__BIG_ENDIAN_BITFIELD)__u8version:4,  ihl:4;#else#error"Please fix <asm/byteorder.h>"#endif__u8tos;__be16tot_len;__be16id;__be16frag_off;__u8ttl;__u8protocol;__sum16check;__be32saddr;__be32daddr;/*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在内存中的位置。

0 0
原创粉丝点击