2016-08-04 3 views
0

J'écris un protocole personnalisé dans le noyau Linux. J'utilise les structures suivantesProblème d'alignement de la mémoire dans les paquets réseau reçus

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 
}; 

Quand j'envoyer et recevoir des paquets, je cartographier les structures syn et ack (pour les paquets différents) à l'adresse de HDR-> type.

Cela devrait idéalement signifier que l'ID (dans les structures syn et ack) doit être mis en correspondance avec le hdr->type et tout ce qui suit le struct hdr doit être mis en correspondance soit syn->cookie ou ack->sequence, selon le struct je cartographie sur le hdr->type .

Mais l'impression des adresses mémoire pour ces variables, je reçois le texte suivant

//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 

Alors pourquoi syn->cookie et ack->sequence départ à différents décalages par rapport à hdr->type lorsque ack->id et syn->id ont la même taille?

EDIT 1: I carte Ces structures à l'aide

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

mot clé ici est * alignement * ... – Nim

+0

Que voulez-vous dire par « Je cartographier les structures syn et ack (pour les paquets différents) à l'adresse de HDR-> type. »? Je sens un comportement indéfini pour accéder à un objet avec une lvalue d'un type qui n'est pas le type effectif de l'objet et/ou l'accès hors limites. – EOF

+0

Oui, je comprends cela, mais j'ai besoin d'un moyen de m'assurer que je puisse accéder au paquet de la même manière à chaque fois, même si je l'ai rempli en utilisant différentes structures –

Répondre

1

puisque vous travaillez en 64 bits le compilateur remplit struct les éléments suivants:

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

Je suppose que les données ne dispose pas de trous , donc pour le réparer, vous devrez mettre seq à uint32_t et le lancer plus tard.

+0

Cela a du sens. Je vais essayer cela et signaler :) –

+0

Je crois cependant que cela rendra l'accès à la mémoire lente [lire ici] (http://www.catb.org/esr/structure-packing/) –

0

Vous devez définir votre structure comme suit. Attribut empaqueté signifie que l'allignement doit être de 1 octet. La structure suivante aura une longueur de 12 octets. Si vous n'utilisez pas le mot-clé "attribyte", votre structure aurait une longueur de 16 octets.

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