7

Netfilterフックを使用してTCPヘッダー情報の一部を変更するカーネルモジュールを作成しています。明らかに、送信する前に、チェックサムを再計算したいと思います。
受信側のヘッダーも編集しているので、そこでも再計算する必要があります。

オンラインで検索すると、0に設定するだけで計算されると言っている人がいましたが、うまくいかなかったようです。
私もこの関数を見つけました

tcp_v4_send_check(struct sock *sk, struct sk_buff *skb);

これがどのように使われるのか、そして私が実際に受信/送信で同じように使用できるかどうかについては誰も説明していませんでした。
私自身の試みは、チェックサムを0に設定してから、この関数を呼び出して、私が持っているskbと私が持っているskb-> skを渡して、まだ何もしないことでした。

では、TCPデータグラムのチェックサムを計算する簡単な方法は何ですか?

4

3 に答える 3

3

チェックサムを再計算するには、増分チェックサムを計算する方が適切です。パケット全体を読み取るのではなく、変更したフィールドに基づいて既存のチェックサムを変更するだけです。

これは、パケットを変更しているときに、保存する古い値と新しい値の両方がわかっているときに実行する必要があります。

基本的な考え方はtcp->check += (new_val - old_val)です。
これよりも少し複雑です。理由は次のとおりです。1。16
ビット値である必要がold_valありnew_valます。16ビット値は2バイトに整列されます(ポート番号の変更など)。
2.チェックサムは1の補数演算を使用するため、「キャリーフィードバック」を実行する必要があります。これは基本的に、tcp->check + new_val - old_val負の場合、結果から1を引く必要があることを意味します。

于 2012-07-10T10:42:59.167 に答える
1

次に、netfilter APIとTCP(IPではない)のチェックサムを組み合わせた例を示します。

http://www.linuxvirtualserver.org/software/tcpsp/index.html

tcpsp_core.cというファイルを調べます。

    th->check = 0;
    th->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
                                  datalen, iph->protocol,
                                  csum_partial((char *)th, datalen, 0));
    skb->ip_summed = CHECKSUM_UNNECESSARY;

(最初にゼロが割り当てられ、チェックサムが計算され、次にIPチェックサムが不要として示されていることに注意してください)。

どのnetfilterモジュールuがロードするか(たくさんあります!!!)に応じて、それらは異なるレイヤーで動作します。たとえば、IPレイヤーで動作するiptableを以下に示します(画像)。

http://ars.sciencedirect.com/content/image/1-s2.0-S1389128608004040-gr3.jpg

于 2012-07-15T12:13:11.133 に答える
1

@ugorenの答えは正確ではありません。RFC1624 https://www.rfc-editor.org/rfc/rfc1624によると、これにより-0(0xFFFF)が生成されることがありますが、これは許可されていません。

チェックサムを計算する正しい方法は次のとおりです。 new_tcp_check = ~(~old_tcp_check + ~old_val + new_val)

于 2017-06-30T00:54:05.067 に答える