简体   繁体   English

Raspberry Pi上的endianess问题

[英]Problems with endianess on Raspberry Pi

I've just started on some raw network programming in C++ and have been compiling on my Raspberry Pi itself (no cross-compiling). 我刚开始使用C ++进行一些原始网络编程,并且已经在我的Raspberry Pi上进行编译(没有交叉编译)。 That makes everything little endian. 这使得一切都变成了小尾数。

After constructing my IP header, I calculate the IP checksum, but it was always coming out incorrect (based on an example here http://www.thegeekstuff.com/2012/05/ip-header-checksum/ ). 在构建我的IP头之后,我计算了IP校验和,但它总是出错(基于这里的例子http://www.thegeekstuff.com/2012/05/ip-header-checksum/ )。

Revving up gdb, I've worked my issue down to the ordering of the first 32 bits in the IP header. 升级gdb,我把我的问题解决了IP头中前32位的排序。 The example uses 0x4500003C , which means version 4 ( 0x4 ), IHL 5 ( 0x5 ), TOS 0 ( 0x00 ), and tot_length 60 ( 0x003C ). 该示例使用0x4500003C ,即版本4( 0x4 ),IHL 5( 0x5 ),TOS 0( 0x00 )和tot_length 60( 0x003C )。 So I set my packet up the same. 所以我把我的数据包设置为相同。

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

Now in gdb, I examined the first 32 bits, expecting 0x3C000045 because of endianness, but instead I get this: 现在在gdb中,我检查了前32位,由于字节顺序而期待0x3C000045 ,但我得到了这个:

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

The first 16 bits are in little endian ( 0x0045 ) but the second, containing decimal 60, seem to be in big endian ( 0x003C )! 前16位是小端( 0x0045 ),但第二位是十进制60,似乎是大端( 0x003C )!

What is giving this? 是什么给这个? Am I crazy? 我疯了吗? Am I completely wrong about byte order inside structs? 我对结构体内的字节顺序完全错了吗? (It's a definite possibility) (这是一个明确的可能性)

There's the order of fields within the struct, and then there's the order of bytes within a multibyte field. 结构中的字段顺序,然后是多字节字段中的字节顺序。

0x003C isn't endian at all, it's the hex value for 60. Sure, it's stored in memory with some endianness, but the order you used to write the field and the order you used to read it back out are the same -- both are the native byte order of the Raspberry Pi, and they cancel out. 0x003C根本不是字节序,它是60的十六进制值。当然,它以一些字节顺序存储在内存中,但是你用来写字段的顺序和用来读取它的顺序是相同的 - 两者都是是Raspberry Pi的本机字节顺序,它们取消了。

Typically you will want to write: 通常你会想写:

ip->tot_len = htons(60);

when storing a 16-bit field into a packet. 将16位字段存储到数据包中时。 There's also htonl for 32-bit fields, and ntohs and ntohl for reading fields from network packets. 还有用于32位字段的htonl ,以及用于从网络数据包读取字段的ntohsntohl

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM