struct iphdr中的__LITTLE_ENDIAN_BITFIELD和__BIG_ENDIAN_BITFIELD

__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在内存中的位置。

时间: 2024-10-28 15:27:50

struct iphdr中的__LITTLE_ENDIAN_BITFIELD和__BIG_ENDIAN_BITFIELD的相关文章

struct框架中实体类中属性的类型错误问题

在struct框架中,我们会写出实体类然后再sqlmap中进行映射,通常我们都知道 java中date类型有java.sql.date 和 java.util.date 经过细心发现,将对象生成为json对象时,json类会将date类型转换成java.util.date 如果在实体类中写成java.sql.date,就会抛出异常 下面我就来传个图 这里仅仅只需要把实体中date类型导入的包改成util的便不会出错 有人说util的包更常用,其实sql包中的直接输入就和我们平时写的时间的差不多,

python struct.pack中的对齐字节问题

最近测试涉及到了序列字节化相关问题,碰到一个头疼的问题 buff = struct.pack("3s","B00")    print repr(buff) 输出:'B00' buff = struct.pack('i',10172) print repr(buff) 输出:"\xbc'\x00\x00" buff = struct.pack("3si","B00",10172)print repr(buf

linux源码分析之IP(1) -- ip.h

在IP层的分组叫做数据报.本节主要介绍数据报的格式,以及在 linux 中是如何定义IP分组头格式. 首先,数据报的格式如下: 其中: 1.版本:有版本4和版本6 2.首部长度:定义数据报的总长度,以4字节为单位计算.首部长度在 20~60字节之间. 3.服务类型:前三位为优先位,后面两位为TOS位,最后一位没有使用. 4.总长度:定义以字节计的数据报总长度(首部加上数据),故数据报长度限制为65535 5.标识:标志从源主机发出的数据报.该字段和Flags和Fragment Offest字段联

字节序(byte order)和位序(bit order)

字节序(byte order)和位序(bit order) ?在网络编程中经常会提到网络字节序和主机序,也就是说当一个对象由多个字节组成的时候需要注意对象的多个字节在内存中的顺序. ?以前我也基本只了解过字节序,但是有一天当我看到ip.h中对IP头部结构体struct iphdr的定义时,我发现其中竟然对一个字节中的8个比特位也区分了大小端,这时我就迷糊了,不是说大小端只有在多个字节之间才会有区分的吗,为什么这里的定义却对一个字节中的比特位也区分大小端呢? ?下面我们先看一下struct iph

Linux程序设计学习笔记----网络编程之网络数据包拆封包与字节顺序大小端

网络数据包的封包与拆包 过程如下: 将数据从一台计算机通过一定的路径发送到另一台计算机.应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header),称为封装(Encapsulation),如下图所示: 不同的协议层对数据包有不同的称谓,在传输层叫做段(segment),在网络层叫做数据包(packet),在链路层叫做帧(frame).数据封装成帧后发到传输介质上,到达目的主机后每层协议再剥掉相应的首部,最后将应用层数据交给应用程序处理. 上图对应两台计算机在同一网段中的情况,

linux内核网络协议栈架构分析,全流程分析-干货

https://download.csdn.net/download/wuhuacai/10157233 https://blog.csdn.net/zxorange321/article/details/75676063 LINUX内核协议栈分析 目  录 1      说明...4 2      TCP协议...4 2.1       分层...4 2.2       TCP/IP的分层...5 2.3       互联网的地址...6 2.4       封装...7 2.5       

Linux基础(11)原始套接字

一边接收函数返回一边判断返回值时一定要把接收的优先级加()提高再去判断 例 if((sockfd = socket()) < 0) 问题: 如何实现SYN扫描器扫描端口 , 比如AB两个设备要进行连接 , A通过端口发一个SYN包给B,B在收到后返回一个ACK包确认连接 , 但是在不确定B端口号时 该如何进行连接 , 答: A给B的每一个端都发一个SYN包, 如果哪个有返回说明端口是开放的, TCP和UDP都无法发实现这样的连接方式 , 所以要使用原始套接字 #include <netinet

python中的struct

我们知道python只定义了6种数据类型,字符串,整数,浮点数,列表,元组,字典.但是C语言中有些字节型的变量,在python中该如何实现呢?这点颇为重要,特别是要在网络上进行数据传输的话. python提供了一个struct模块来提供转换.下面就介绍这个模块中的几个方法. struct模块中最重要的三个函数是pack(), unpack(), calcsize() # 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流) pack(fmt,v1, v2, ...) #

python中struct模块及packet和unpacket

转自:http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html 我们知道python只定义了6种数据类型,字符串,整数,浮点数,列表,元组,字典.但是C语言中有些字节型的变量,在python中该如何实现呢?这点颇为重要,特别是要在网络上进行数据传输的话. 有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用python的struct模块来完成.可以用 struct来处理c语言中的结构体. st