1

IP チェックサムを再計算する必要がある netfilter カーネル モジュールを開発しています。この関数を使用して IP チェックサムを計算しました (インターネット上のどこかで見つけました)。

unsigned short ComputeIPChecksum(unsigned char *data, int len)
{
         long sum = 0;  /* assume 32 bit long, 16 bit short */
     unsigned short *temp = (unsigned short *)data;

         while(len > 1){
             sum += *temp++;
             if(sum & 0x80000000)   /* if high order bit set, fold */
               sum = (sum & 0xFFFF) + (sum >> 16);
             len -= 2;
         }

         if(len)       /* take care of left over byte */
             sum += (unsigned short) *((unsigned char *)temp);

         while(sum>>16)
             sum = (sum & 0xFFFF) + (sum >> 16);

        return ~sum;
}

Wireshark を見ると、着信パケットは正常に受信されていることがわかりますが、発信パケットについては、wireshark が誤った IP チェックサムを示しています。これが私のフック関数です:

static unsigned int hook_func(unsigned int hooknum,
                        struct sk_buff *skb,
                                const struct net_device *in,
                                const struct net_device *out,
                                int (*okfn)(struct sk_buff *))
{
    sock_buff = skb; 

    if (sock_buff)
    {
            ip_header = (struct iphdr *)skb_network_header(sock_buff);
            if (ip_header && ip_header->protocol == TCP)
            {
                ip_header->check = ComputeIPChecksum((unsigned char *)ip_header, ip_header->ihl*4);
            }
    }
    return NF_ACCEPT;
}

これがメインです。同じフック関数を PRE_ROUTING と POST_ROUTING にバインドしました

static int __init init_main(void)
{
    nfho.hook     = hook_func;
    nfho.hooknum  = 0;
    nfho.pf       = PF_INET;
    nfho.priority = NF_IP_PRI_FIRST;

    nfho1.hook     = hook_func;
    nfho1.hooknum  = 4;
    nfho1.pf       = PF_INET;
    nfho1.priority = NF_IP_PRI_FIRST;

    nf_register_hook(&nfho);
    nf_register_hook(&nfho1);

    return 0;
}

送信パケットの IP チェックサムが破損するのはなぜですか???

Wireshark に表示されるエラー:

Header checksum: 0x0000 [incorrect, should be 0x85de (maybe caused by "IP checksum offload"?)]
4

2 に答える 2

1

どこでパケットをキャプチャしていますか?

IP チェックサム (および TCP/UDP チェックサム) は、ネットワーク カード自体で計算できます。これがカードに当てはまり (非常に一般的な機能です)、マシンでキャプチャしている場合、チェックサムは 0 であると予想されます。

于 2012-04-29T13:43:06.853 に答える
0

次のように IP ヘッダーを定義した場合:

struct iphdr *iph;

その後

iph = (struct iphdr *) skb_header_pointer(skb, 0, 0, NULL);

次に、次のようにチェックサムを再計算できます。

/* Calculation of IP header checksum */
iph->check = 0;
ip_send_check (iph);

私の質問を見ているかもしれません:カーネル空間からパケットにデータを追加する方法は? 下部にある特定の回答で詳細コードを見つけることができます。そこで、IP および UDP ヘッダーのチェックサムを再計算する必要がありました。

于 2012-11-02T13:08:03.713 に答える