次のことを想定しましょう。
UDPパケットの構造を作成したいと思います。各フレームは通常、イーサネットヘッダー、IPヘッダー、UDPヘッダー、オプションのペイロードで構成され、最後にFCS(フレームチェックサムシーケンス)が続きます。
ペイロードの長さは不明/柔軟です。つまり、構造体を作成するとき、ペイロードはその最後のメンバー(柔軟な配列メンバー)である必要があります。したがって、FCSの場所はありません。
そこで、どんな可能性が残るのか考えました。
私は次のコードを思いついた:
#define UDP_PKT(name, payload_length) struct __attribute((__packed__)) \
{ \
struct ether_header eth; \
struct ip iph; \
struct udphdr udph; \
unsigned char payload[payload_length]; \
u_int32_t fcs; \
} name;
これは許可されていないため:
struct __attribute__((__packed__)) udp_packet
{
struct ether_header eth;
struct ip iph;
struct udphdr udph;
unsigned char payload[]; // fam, must always be the last member
u_int32_t fcs;
};
私の質問:固定配列(ペイロード)サイズを持たずに構造にFCSを含める必要がある唯一の可能性はありますか?
もしそうなら、それは良い解決策ですか?それは良い習慣と考えられていますか?
struct
フレキシブル配列メンバーのサイズは実行時に決定されるため、最初のアプローチも機能しません。解決策はstruct
、ワイヤー用にシリアル化する準備ができたら、FCSをバッファーの最後に配置することです。
struct __attribute__((__packed__)) udp_packet {
struct ether_header eth;
struct ip iph;
struct udphdr udph;
u_int32_t fcs;
unsigned char payload[]; // Move fcs up
};
void serialize_udp_packet(const udp_packet* p) {
// Compute buffer size, and allocate the buffer
// Place the header into the buffer
// Copy the payload into the buffer
// Place FCS into the buffer at the end
}
を完全に除外fcs
して、udp_packet
をシリアル化した場合にのみ計算することもできますstruct
。このアプローチの利点の1つはFCS
、変更されたペイロードに常に同期しなくても、ペイロードを自由に変更できることです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加