2016-08-04 51 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 
}; 

當我發送和接收包,我的結構synack和(爲不同的數據包)映射到HDR-的地址>輸入。

這理想地應該意味着ID(在SYN和ACK結構)可以被映射到hdr->type和任何隨後的struct hdr應當映射到syn->cookieack->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->typeack->idsyn->id具有相同的大小?

編輯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

你說的「我映射結構SYN和ACK(對於不同的數據包),以HDR-的>鍵入地址。」是什麼意思?我聞到未定義的行爲,用於訪問具有非對象有效類型的左值對象和/或訪問超出範圍的對象。 – 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

您應該如下定義您的結構。屬性打包意味着allignment應該爲1個字節。 以下結構將是12個字節長。如果你不使用「attribyte」關鍵詞,你的結構將是16字節長。

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