Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with endianess on Raspberry Pi

Tags:

c++

endianness

I've just started on some raw network programming in C++ and have been compiling on my Raspberry Pi itself (no cross-compiling). 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/).

Revving up gdb, I've worked my issue down to the ordering of the first 32 bits in the IP header. The example uses 0x4500003C, which means version 4 (0x4), IHL 5 (0x5), TOS 0 (0x00), and 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) 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)!

What is giving this? Am I crazy? Am I completely wrong about byte order inside structs? (It's a definite possibility)

like image 706
John Sandbrook Avatar asked Oct 01 '12 23:10

John Sandbrook


People also ask

Is Raspberry pi little endian or big-endian?

The Endianness is a property of the CPU ... and on the Raspberry it is Little-Endian. It is not possible to boot into "Big-Endian"-Mode, because the CPU won't understand one single instruction.

When should I worry about endianness?

The times when you need to worry about endianess: you are sending binary data between machines or processes (using a network or file). If the machines may have different byte order or the protocol used specifies a particular byte order (which it should), you'll need to deal with endianess.

Why is endianness necessary?

So knowledge of endianness is important when you are reading and writing the data across the network from one system to another. If the sender and receiver computer have different endianness, then the receiver system would not receive the actual data transmitted by the sender.

Is Intel Little endian?

For example, Intel processors have traditionally been little-endian. Motorola processors have always been big-endian. Big-endian is an order in which the "big end" (the most-significant byte) is stored first. Little-endian is an order in which the "little end" (the least-significant byte) is stored first.


1 Answers

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.

Typically you will want to write:

ip->tot_len = htons(60);

when storing a 16-bit field into a packet. There's also htonl for 32-bit fields, and ntohs and ntohl for reading fields from network packets.

like image 83
Ben Voigt Avatar answered Oct 21 '22 22:10

Ben Voigt