インターネットチェックサム[ 1 ] [ 2 ]は、 IPv4ヘッダーチェックサムとも呼ばれ、 IPv4パケットのヘッダーの破損を検出するためにインターネットプロトコルバージョン4(IPv4)で使用されるチェックサムです。これはIPv4パケットヘッダーに含まれ、ヘッダーワードの合計の16ビットの結果を表します。[ 3 ]
IPv6プロトコルはヘッダーチェックサムを使用しません。設計者は、PPPやイーサネットなどのプロトコルで提供されるパケット全体のリンク層チェックサムと、 TCPやUDPなどの上位層プロトコルでのチェックサムの使用を組み合わせることで十分であると考えました。[ 4 ]そのため、IPv6ルータは、ホップごとにホップ制限カウンタを下げるなどしてパケットが変更されるたびにチェックサムを再計算するタスクから解放されます。
IPv6 UDPパケット(データペイロードを含む)のエラーを検出するには、インターネットチェックサムが必須です。
インターネットチェックサムは、ICMPパケット(データペイロードを含む)のエラーを検出するために使用されます。
チェックサムの計算は次のように定義されます。[ 5 ]
チェックサムフィールドは、ヘッダー内のすべての16ビットワードの1の補数和の16ビット1の補数です。チェックサムを計算する際には、チェックサムフィールドの値はゼロになります。
破損がない場合、チェックサムを含むIPヘッダー全体を合計し、その1の補数を取ると、結果はゼロになるはずです。各ホップでチェックサムが検証されます。チェックサムが一致しないパケットは破棄されます。ルーターは、IPヘッダーを変更する場合(TTLをデクリメントする場合など)は、チェックサムを調整する必要があります。[ 6 ]
この手順はRFC 1071「インターネットチェックサムの計算」 [ 1 ]で詳しく説明されています。RFC 1624「増分更新によるインターネットチェックサムの計算」[ 2 ]では、単一のフィールドのみが変更されたパケット転送中にヘッダーチェックサムを再計算する必要があるルータの場合をカバーするための最適化が示されています。
RFCによるインターネットチェックサムアルゴリズムは次のとおりです。[ 7 ]
int checksum ( int count , void * addr ){ /*アドレス "addr" から始まる"count" バイトのインターネット チェックサムを計算します。 */ long sum = 0 ; while ( count > 1 ){ sum += * ( unsigned short ) addr ++ ; count -= 2 ; } /* 余ったバイトがあれば加算します。 */ if ( count > 0 ){ sum += * ( unsigned char * ) addr ; } /* 32 ビットの合計を 16 ビットに折り返します。 */ while ( sum >> 16 ){ sum = ( sum & 0xffff ) + ( sum >> 16 ); } long checksum = ~ sum ; }以下は、IPv4パケットの一部を切り取ったものです。ヘッダーは太字で、チェックサムは下線で示されています。
4500 0073 0000 4000 4011 b861 c0a8 0001c0a8 00c7 0035 e97c 005f 279f 1e4b 8180
1の補数加算では、桁上がりが発生するたびに、合計に1を追加する必要があります。[ 8 ]桁上がりチェックと修正は、各加算で実行することも、すべての加算の後の事後処理として実行することもできます。修正によって別の桁上がりが発生した場合は、合計に別の1が追加されます。
チェックサムを計算するには、まずヘッダー内の各16ビット値の合計を計算します。ただし、チェックサムフィールド自体は除外します。これらの値は16進数表記であることに注意してください。
初回追加:4500 + 0073 + 0000 + 4000 + 4011 + 0000[a] + c0a8 + 0001 + c0a8 + 00c7 = 2479c
キャリー加算は、5番目の16進数を最初の4桁に加えることによって行われます。2 + 479c = 479e
チェックサムは、この結果の1の補数(ビットごとのNOT )です。NOT 479e = b861
このチェックサム値は、上記の元のIPパケットヘッダーで下線付きで示されています。
チェックサムを検証する場合、上記と同じ手順を使用しますが、元のヘッダーチェックサムは省略しません。 4500 + 0073 + 0000 + 4000 + 4011 + b861 + c0a8 + 0001 + c0a8 + 00c7 = 2fffd キャリービットを追加します。1 fffd + 2 = ffff の補数を取る(すべてのビットを反転する)と0000になり、エラーが検出されなかったことを示します。IPヘッダーチェックサムは、ヘッダー内の16ビット値の正しい順序をチェックしません。
0000は計算前の初期チェックサム値であり、計算手順にも含まれています。