UDPチェックサムは、ペイロード全体、ヘッダー内の他のフィールド、およびIPヘッダーの一部のフィールドに対して実行されます。計算を実行するために、IPヘッダーから疑似ヘッダーが作成されます(これは、この疑似ヘッダー、UDPヘッダー、およびペイロードに対して実行されます)。疑似ヘッダーが含まれている理由は、間違ったIPアドレスにルーティングされたパケットをキャッチするためです。
基本的に、受信側では、ヘッダーのすべての16ビットワードとデータ領域が加算され(16ビットでラッピング)、結果がと照合されます0xffff
。
送信側では、もう少し複雑です。1の補数の合計がすべての16ビット値に対して実行され、次に1の補数(つまり、すべてのビットを反転)がその値から取得され、チェックサムフィールドに入力されます(計算されたゼロのチェックサムがすべてに変更されるという追加の条件があります) 1ビット)。
1の補数の合計は、すべての1の補数の値の合計だけではありません。もう少し複雑です。
基本的に、ゼロから始まる実行中の16ビットアキュムレータがあり、それにすべての16ビット値を追加します。これらの追加のいずれかがキャリーになる場合は常に、値がラップアラウンドされ、値に1を再度追加します。これにより、16ビット加算のキャリービットが効果的に取得され、値に加算されます。
余談ですが、これは私の側の純粋な推測ですが、これはおそらく(驚くべきことに、追加)ADC
ではなく(キャリーで追加)命令、またはその時点でCPUで利用可能な同等の命令を使用することで効率的に実行できますADD
。
キャリーがなかった場合は、キャリーADC
からゼロビットを追加するだけです。このようなことが行われていた時代(そして、残念ながら、私はとても古いです)、メモリは速度よりもはるかに制約があり、最近はそれほど多くはありませんでした。そのため、コードに数バイトを節約すると、宇宙の半神皇帝のレベル:-)
ADC
2つの最大の16ビット値を合計すると(切り捨てられる)、2回目のキャリー(または前の段落で説明した方法を使用している場合は次のキャリー)について心配する必要がないことに注意してください。 from 0x1fffe
)0xfffe
-それに1つ追加しても、別のキャリーが発生することはありません。
計算された1の補数の合計が計算され、ビットが反転されてパケットに挿入されると、0xffff
もちろん送信にエラーがないと仮定すると、受信側での計算でが生成されます。
16ビットワードの整数が確実に存在するように、ペイロードは常にパディングされることに注意してください。パディングされている場合、長さフィールドに実際の長さが表示されます。
RFC768は、これを詳述する仕様です。