2016-08-04 1 views
0

Я пишу собственный протокол в ядре linux. Я использую следующие структурыПроблема выравнивания памяти в принятых сетевых пакетах

struct syn { 
    __be32 id;  
    __be64 cookie; 
}; 

struct ack { 
    __be32 id;  // Right now, setting it to 14 (Just a random choice) 
    __be32 sequence; 
}; 

struct hdr { 
    ............ 
    __be32 type; //last element 
}; 

Когда я отправлять и получать пакеты, я карту структуры syn и ack (для разных пакетов) на адрес HDR-> типа.

Это в идеале должен означать, что идентификатор (в сине и Ack структур) должен быть сопоставлен с hdr->type и все, что следует за struct hdr должно быть отображено в любом syn->cookie или ack->sequence, в зависимости от которой структуры Я отображение на к hdr->type ,

Но распечатывания адреса памяти для этих переменных, я получаю следующее

//For struct syn 
hdr->type at ffff880059f55444 
syn->id at ffff880059f55444 
syn->cookie at ffff880059f5544c //See the last two bits 

//For struct ack_frame 
hdr->type at ffff880059f55044 
ack->id at ffff880059f55044 
ack->sequence at ffff880059f55048 //See the last two bits 

Так почему же syn->cookie и ack->sequence запуск при различных смещениях относительно hdr->type когда ack->id и syn->id имеют одинаковый размер?

EDIT 1: Я сопоставить эти структуры с помощью

char *ptr = (char *)&hdr->type; 
//For syn 
struct syn *syn1 = (struct syn *)ptr 
//For ack 
struct ack *ack1 = (struct ack *)ptr 
+0

ключевое слово здесь * выравнивание * ... – Nim

+0

Что вы имеете в виду под «I карта структуры син и извед (для разных пакетов) по адресу> Тип HDR-».? Я ощущаю неопределенное поведение для доступа к объекту с lvalue типа, который не является эффективным типом объекта и/или выходит за пределы. – EOF

+0

Да, я это понимаю, но мне нужен способ убедиться, что я получаю доступ к пакету одинаково каждый раз, даже если я его заполняю с использованием разных структур. –

ответ

1

, поскольку вы работаете в 64-бит компилятор заполняет структура следующее:

struct syn { 
    uint32_t id 
    uint32_t hole -- the compiler must add here cause it mist align 
    uint64_t seq 
} 

Я предполагаю, что данные не имеют отверстий , поэтому, чтобы исправить это, вам нужно будет установить seq в uint32_t и затем произнести его позже.

+0

Делает смысл. Я попробую это и сообщите :) –

+0

Я верю, однако, что это сделает доступ к памяти медленным [читайте здесь] (http://www.catb.org/esr/structure-packing/) –

0

Вы должны указать структуру, как показано ниже. Атрибут упакованных означает, что присвоение должно быть как 1 байт. Следующая структура будет длиной 12 байт. Если вы не используете ключевое слово «атрибут», ваша структура будет иметь длину 16 байт.

struct yours{ 
__be32 id;  
__be64 cookie; 
}__attribute__((__packed__));