2016-08-04 14 views
0

私はLinuxカーネルにカスタムプロトコルを書いています。私はhdr-のアドレスにsynack(異なるパケット用)の構造をマッピングするには、次の構造 受信したネットワークパケットのメモリアラインメントの問題

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構造で)idはhdr->typeにマッピングする必要がありますし、何でもstruct hdrを以下のは、私がhdr->typeへマッピングするよどの構造体に依存し、syn->cookieまたはack->sequenceのいずれかにマッピングされるべきであることを意味する必要があります。

しかし、これらの変数のメモリアドレスをプリントアウトの上、私は次の

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

を取得ack->idsyn->idが同じサイズを持っているとき、なぜhdr->typeに対して異なるオフセットでsyn->cookieack->sequence開始しますか?

EDIT 1:あなたは64ビットのコンパイラで作業するので、私は

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

キーワードは*アライメント* ... – Nim

+0

あなたは「私はhdr-のアドレス>を入力する(異なるパケットのために)構造がSYNとACKマップ。」とはどういう意味ですかいるのですか?私は、オブジェクトの有効な型ではない型の左辺値を持つオブジェクトにアクセスする、および/または境界外にアクセスする、未定義の振る舞いを嗅ぐ。 – EOF

+0

はい、私は理解していますが、別の構造を使用してパケットを入力しても、毎回同じ方法でパケットにアクセスできるようにする方法が必要です –

答えて

1

を使用してこれらの構造をマップし、次の構造体の塗りつぶし:私は、データが穴を持っていないと思い

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バイトの長さになります。 "attribyte"キーワードを使用しないと、構造は16バイトになります。ここ

struct yours{ 
__be32 id;  
__be64 cookie; 
}__attribute__((__packed__)); 
関連する問題