パケットの正しい IP チェックサムを計算するのに問題があります。これがコードです。私が何をしていて、何が間違っているのかを説明します..
u_short checkSum(u_short *data, int byteCount){
int i, sum = 0;
for(i = 0; i < byteCount/2; i++){
if(i == 5) continue;
sum += *data++;
}
while(sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
return (u_short)~sum;
}
まず、私の関数は、送信されたデータの 16 ビット チェックサムを計算するための一般的なものです。バイト数は、テスト目的のためだけに均等であると想定されています。sum は、32 ビットの合計を保持する変数です (16 ビットの合計がオーバーフローした場合、上位 16 ビットの半分にオーバーフローを保持できます)。データの 16 ビット ブロックを介して for i ループを使用してそれらを合計し、データ ポインターをインクリメントします (16 ビットずつ u_short です)。ヘッダーのチェックサム部分をスキップする if テストが 1 つあります。 rfc 791 では、チェックサム部分はヘッダーの 6 番目の 16 ビット ブロックです (0 からカウントを開始するため、私の場合は 5 です)。データが合計された後、上位 16 ビットを下位 16 ビットに加算し、32 ビット int を 16 ビット short に折りたたみます。最後に、ビット (1 の補数) を反転し、32 ビットを 16 ビットに短縮して呼び出し元関数に返します。
これは、pcap から送信された正しいチェックサムを提供していません (パケットのスニッフィングに使用します)。これは、結果を比較するために関数を呼び出す方法です..
if(etherHdr->ether_type == 8){
ipHdr = (struct ip*) (packet + sizeof(struct ether_header));
printf("chck: %04x mychck: %04x\n\n", ipHdr->ip_sum, checkSum((u_short*)ipHdr, sizeof(struct ip)));
}
if は、IP パケット (イーサネット ヘッダー タイプ フィールドのコード 8) のみをフィルタリングしています。
これは、プログラムを実行したときの出力です..
chck: ef66 mychck: 06ee
チェック: 3db8 mychck: 0264
chck: 9615 mychck: 0000
chck: edef mychck: ff64
chck: 59f1 mychck: 0164
chck: 49f1 mychck: 0264
chck: a3d4 mychck: 0c77
チェック: e36b mychck: 0264
チェック: aad4 mychck: 0c77
chck: 46d1 mychck: 0c77
chck: f40b mychck: 0264
chck: a8d4 mychck: 0c77
ネット上で実行されている他のコード例をダウンロードしましたが、pcapがパケットをコードに転送するときに、すべてのIPヘッダーに含まれる結果はどちらも得られません..
できれば助けてください、ありがとう。