27

/usr/include/netinet/udp.hで定義されているUDPヘッダー構造体は次のとおりです。

struct udphdr
{
  u_int16_t source;
  u_int16_t dest;
  u_int16_t len;
  u_int16_t check;
};

ヘッダーのチェックフィールドにはどのような値が格納されますか?チェックサムが正しいかどうかを確認するにはどうすればよいですか?チェックサムはどのデータで計算されるのですか?(それは、udpヘッダーまたはudpヘッダーとそれに続くペイロードだけですか?)

ありがとう。

4

3 に答える 3

40

UDPチェックサムは、ペイロード全体、ヘッダー内の他のフィールド、およびIPヘッダーの一部のフィールドに対して実行されます。計算を実行するために、IPヘッダーから疑似ヘッダーが作成されます(これは、この疑似ヘッダー、UDPヘッダー、およびペイロードに対して実行されます)。疑似ヘッダーが含まれている理由は、間違ったIPアドレスにルーティングされたパケットをキャッチするためです。

基本的に、受信側では、ヘッダーのすべての16ビットワードとデータ領域が加算され(16ビットでラッピング)、結果がと照合されます0xffff

送信側では、もう少し複雑です。1の補数の合計がすべての16ビット値に対して実行され、次に1の補数(つまり、すべてのビットを反転)がその値から取得され、チェックサムフィールドに入力されます(計算されたゼロのチェックサムがすべてに変更されるという追加の条件があります) 1ビット)。

1の補数の合計は、すべての1の補数の値の合計だけではありません。もう少し複雑です。

基本的に、ゼロから始まる実行中の16ビットアキュムレータがあり、それにすべての16ビット値を追加します。これらの追加のいずれかがキャリーになる場合は常に、値がラップアラウンドされ、値に1を再度追加します。これにより、16ビット加算のキャリービットが効果的に取得され、値に加算されます。


余談ですが、これは私の側の純粋な推測ですが、これはおそらく(驚くべきことに、追加)ADCではなく(キャリーで追加)命令、またはその時点でCPUで利用可能な同等の命令を使用することで効率的に実行できますADD

キャリーがなかった場合は、キャリーADCからゼロビットを追加するだけです。このようなことが行われていた時代(そして、残念ながら、私とても古いです)、メモリは速度よりもはるかに制約があり、最近はそれほど多くはありませんでした。そのため、コードに数バイトを節約すると、宇宙の半神皇帝のレベル:-)


ADC2つの最大の16ビット値を合計すると(切り捨てられる)、2回目のキャリー(または前の段落で説明した方法を使用している場合は次のキャリー)について心配する必要がないことに注意してください。 from 0x1fffe0xfffe-それに1つ追加しても、別のキャリーが発生することはありません。

計算された1の補数の合計が計算され、ビットが反転されてパケットに挿入されると、0xffffもちろん送信にエラーがないと仮定すると、受信側での計算でが生成されます。

16ビットワードの整数が確実に存在するように、ペイロードは常にパディングされることに注意してください。パディングされている場合、長さフィールドに実際の長さが表示されます。

RFC768は、これを詳述する仕様です。

于 2009-09-26T06:48:14.537 に答える
2

UDPチェックサム計算の素晴らしくて理解しやすい例はGerdHoffmannによって行われます。

「net-checksum.cGerdHoffmann」をグーグルで検索するか、次のファイルを参照してください。

https://gist.github.com/fxlv/81209bbd150abfeaceb1f85ff076c9f3

関数を使用net_checksum_tcpudpして、UDPペイロードの長さ、proto、src、dst IPをフィードしてから、UDPペイロード自体をフィードすると、正しい処理が実行されます。

最後htons()に、チェックサムを呼び出す必要があり、問題ありません。

于 2016-06-01T06:24:42.320 に答える
0

私はネットでudpヘッダーを計算するコードを探していました(上記の疑似IPヘッダーを使用)。

最後に、open-bsddhclientpacket.cを見つけました。

https://github.com/openbsd/src/blob/master/sbin/dhclient/packet.c

機能をチェックしてくださいassemble_udp_ip_header()

于 2011-09-09T09:34:20.957 に答える