簡體   English   中英

如何計算TCP校驗和

[英]How to calculate TCP checksum

我正在編寫一個使用Netfilter掛鈎修改一些TCP頭信息的內核模塊,顯然,在發送之前,我想重新計算校驗和。
我也在接收端編輯標題,所以我也需要在那里重新計算它。

在網上搜索,我發現有些人說我可以簡單地將它設置為0並且它將為我計算,顯然這不起作用。
我也發現了這個功能

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

雖然沒有人解釋如何使用它,以及我是否可以在接收/發送時以相同的方式使用它。
我自己的嘗試是將校驗和設置為0然后調用此函數傳遞我擁有的skb和我擁有的skb-> sk,仍然沒有。

那么請問,計算TCP數據報校驗和的簡單方法是什么?

要重新計算校驗和,最好計算增量校驗和 - 只需根據已更改的字段修改現有校驗和,而不是讀取整個數據包。

當您知道舊值和存儲的新值時,必須在更改數據包時執行此操作。

基本思路是tcp->check += (new_val - old_val)
這比這復雜一點,因為:
1. old_valnew_val需要是16位值,它們在2個字節上對齊(例如,更改端口號)。
校驗和使用一個補碼算術,所以你需要做“攜帶反饋”。 這基本上意味着,如果tcp->check + new_val - old_val為負數,則需要從結果中減去1。

這是一個結合TCP(而不是IP)的netfilter API +校驗和的示例:

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模塊(有很多!!!)它們將在不同的層工作,例如iptable在IP層工作如下所示(圖像):

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

@ ugoren的回答並不准確。 根據RFC1624 https://tools.ietf.org/html/rfc1624 ,這有時會產生-0(0xFFFF),這是不允許的。

計算校驗和的正確方法應該是: new_tcp_check = ~(~old_tcp_check + ~old_val + new_val)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM