树莓派上的endianes问题

Problems with endianess on Raspberry Pi

本文关键字:endianes 问题      更新时间:2023-10-16

我刚刚开始用C++进行一些原始网络编程,并且一直在我的Raspberry Pi上进行编译(没有交叉编译)。这让一切都变得微不足道。

在构造IP标头后,我计算了IP校验和,但结果总是不正确(基于这里的示例http://www.thegeekstuff.com/2012/05/ip-header-checksum/)。

在升级gdb时,我已经将问题归结为IP头中前32位的顺序。该示例使用0x4500003C,表示版本4(0x4)、IHL5(0x5)、TOS 0(0x00)和tot_length 60(0x003C)。所以我把我的包设置成相同的。

struct iphdr* ip; // Also some mallocing
ip->version = 4;
ip->ihl = 5;
ip->tos = 0;
ip->tot_len = 60;

现在在gdb中,我检查了前32位,由于字节序的原因,我期望0x3C000045,但我得到的却是:

(gdb) print ip
$1 = (iphdr *) 0x11018
(gdb) x/1xw 0x11018
0x11018:        0x003c0045

前16位是小端序(0x0045),但第二位(包含小数点60)似乎是大端序(0x003C)!

这是什么?我疯了吗?我对结构中的字节顺序完全错了吗?(肯定有可能)

结构中有字段的顺序,然后是多字节字段中的字节顺序。

0x003C根本不是endian,它是60的十六进制值。当然,它是以一些endianness存储在内存中的,但写入字段的顺序和读取字段的顺序是相同的——两者都是Raspberry Pi的原生字节顺序,它们相互抵消。

通常你会想写:

ip->tot_len = htons(60);

当将16比特字段存储到分组中时。还有htonl用于32位字段,ntohsntohl用于从网络数据包中读取字段。

ARM体系结构可以运行小端和大端,但Android平台运行小端。