Проблемы с порядком байтов на Raspberry Pi

Я только начал на каком-то простом сетевом программировании на C ++ и собирал на моем Raspberry Pi (без кросс-компиляции). Это делает все немного прямым

После создания заголовка IP я вычисляю контрольную сумму IP, но она всегда получалась неправильной (на примере здесь http://www.thegeekstuff.com/2012/05/ip-header-checksum/).

Обращаясь к gdb, я решил проблему до порядка первых 32 бит в заголовке IP. В примере используются 0x4500003C, что означает версию 4 (0x4), МГП 5 (0x5), TOS 0 (0x00) и общая длина 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)!

Что дает это? Я сумасшедший? Я совершенно не прав насчет порядка байтов внутри структур? (Это определенная возможность)

6

Решение

В структуре есть порядок полей, а в многобайтовом поле — порядок байтов.

0x003C это вовсе не endian, это шестнадцатеричное значение для 60. Конечно, оно хранится в памяти с некоторым порядком байтов, но порядок, который вы использовали для записи поля, и порядок, который вы использовали для его чтения, одинаковы — оба родной порядок байтов Raspberry Pi, и они отменяются.

Обычно вы хотите написать:

ip->tot_len = htons(60);

при сохранении 16-битного поля в пакет. Есть также htonl для 32-битных полей и ntohs а также ntohl для чтения полей из сетевых пакетов.

7

Другие решения

Архитектура ARM может работать как с прямым, так и с малым порядком байтов, но платформа Android работает с прямым порядком байтов.

2

По вопросам рекламы [email protected]