我正在創建一些與模擬以太網標頭的結構一起使用的函式。
typedef struct ethernet_hdr_ {
dir_mac_t dst_mac;
dir_mac_t src_mac;
short type;
char payload[MAX_SIZE_PAYLOAD];
unsigned int FCS;
} ethernet_hdr_t;
#define ETH_HDR_SIZE_EXCL_PAYLOAD (sizeof(ethernet_hdr_t) - sizeof(((ethernet_hdr_t *)0)->payload))
我需要定義下一個函式。
static inline ethernet_hdr_t * ALLOC_ETH_HDR_WITH_PAYLOAD(char *pkt, unsigned int pkt_size)
根據我已經完成的這個作業,但我想知道我的解決方案是否有問題。
上述API必須將現有的DATA封裝到ethernet header的payload中,即上面的API必須回傳一個指向ethernet hdr的指標,其payload攜帶上圖中pkt指向的大小為pkt_size的資料。
具有新以太網 hdr 的資料布局必須與此作業說明中隨附的影像 Q3 中給出的一樣。將不包括有效載荷的新以太網 hdr(包括 FCS)的所有欄位初始化為零。
這是第三季度。

我就是這樣做的。
static inline ethernet_hdr_t * ALLOC_ETH_HDR_WITH_PAYLOAD(char *pkt, unsigned int pkt_size) {
ethernet_hdr_t *ethernet_hdr = calloc(1, sizeof(ethernet_hdr_t));
memcpy(ethernet_hdr->payload, pkt, pkt_size);
return ethernet_hdr;
}
但是,我找到了這個任務的官方解決方案,它與我的非常不同。
static inline ethernet_hdr_t * ALLOC_ETH_HDR_WITH_PAYLOAD(char *pkt, unsigned int pkt_size) {
char *temp = calloc(1, pkt_size);
memcpy(temp, pkt, pkt_size);
ethernet_hdr_t *eth_hdr = (ethernet_hdr_t *)(pkt - ETH_HDR_SIZE_EXCL_PAYLOAD);
memset((char *)eth_hdr, 0, ETH_HDR_SIZE_EXCL_PAYLOAD);
memcpy(eth_hdr->payload, temp, pkt_size);
free(temp);
return eth_hdr;
}
Clearly, my function is much simpler but I think it is missing something. So, I'm wondering whether both solutions are correct, but even if they are, maybe the second one is better.
uj5u.com熱心網友回復:
在您的情況下,您正在創建一個新物件來存盤資料包標頭和有效載荷(幀)資料,將標頭設定為零并將有效載荷從中復制pkt到新的幀資料物件payload成員。
在“官方”解決方案中,程式假定pkt指向payload型別為 的物件的成員ethernet_hdr_t。然后,以一種非常復雜的方式,它嘗試做與您的代碼相同的事情,但使用pkt作為成員的原始物件。
總的來說,我會說“官方”解決方案是有問題的,原因有幾個:
- 它假設編譯器會
struct ethernet_hdr_以特定的方式排列 的內容,但這實際上是由實作定義的。這是由于宏ETH_HDR_SIZE_EXCL_PAYLOAD使用物件和成員payload大小來嘗試payload在struct. 一個更安全的辦法可能是使用標準庫offsetof宏來確定偏移成員payload內struct。 - 假設它
pkt是另一個物件型別的成員并不是一個好的編程習慣。例如,假設payload內容被復制到另一個物件,該物件ethernet_hdr_t在呼叫 之前不是 的成員ALLOC_ETH_HDR_WITH_PAYLOAD。這將導致記憶體訪問沖突。該函式應該只嘗試訪問作為引數提供的物件,而不是這些物件“可能”是其成員的物件。 temp在這個函式中使用的意義不大。有效載荷資料被有效地復制到temp然后pkt通過指向的物件間接復制回eth_hdr。- 生成輸入的物件
ALLOC_ETH_HDR_WITH_PAYLOAD正在由函式更新,回傳的指標將指向同一個物件。這可能會導致任何嘗試使用該功能的人感到困惑。
對于您的代碼,它完成與“官方”答案相同的事情,但會創建一個新物件來包含資料。一旦不再需要物件,您將需要確保正確釋放記憶體,但是在比較兩者時,我認為您的代碼更正確,因為它不會導致未定義、實作定義或混淆的行為.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/315019.html
上一篇:陣列和結構指標
