struct iphdr中的__LITTLE_ENDIAN_BITFIELD和__BIG_ENDIAN_BITFIELD
2015-06-12 22:12
399 查看
__LITTLE_ENDIAN_BITFIELD表示小端序,__BIG_ENDIAN_BITFIELD表示大端序。
/usr/include/linux/ip.h中有一段代码定义了ip首部的结构体,如下:
这里的:4是C语言中的位域,是指取二进制中的低四位(在大端序中这个低四位是存储在高地址的)。
如果使用者只允许直接对ihl或者version成员,那么这一段代码可以不用判断是大端序或者小端序。
但使用者可能使用memcpy来直接对这开头的8位进行赋值操作,而在大端序和小端序的机器上会产生不同的情况。
比如下面这段代码:
在小端序的机器上结果应该是
x[0] x[1]
---------
10 .. 00
而在大端序的机器上结果则是
x[0] x[1]
---------
00 .. 01
注意x[1]的地址都是比x[0]高的。
因此为了提高兼容性(程序可以被小端序和大端序的机器共用),需要预先判断是大端序还是小端序,并调换ihr和version在内存中的位置。
/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在内存中的位置。
相关文章推荐
- 32.文本输入输出
- Qt图形框架资料06
- Qt图形框架资料05
- Qt图形框架资料04
- Qt图形框架资料03
- Qt图形框架资料02
- mysql Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
- android sdk更新下载失败问题
- 清除垃圾的DOS命令
- mysql字符集
- 为什么有装箱和拆箱
- 泛型笔记
- 再读effective c++
- Qt图形框架资料01
- Python模块学习笔记— —random
- White spaces are required between publicId and systemId.异常
- VC拖动控件
- 学习网站
- 婚恋网站跨入免费时代?颠覆还是无奈
- 花生壳帐号无法登录怎么办