[英]C Programming TCP Checksum
幾天來,我一直在為 TCP 進行校驗和處理時遇到問題。 我查看了 Internet 上的許多資源,但我所看到的示例都沒有向您展示如何進行 TCP 校驗和。 我還查看了RFC文檔,但仍然遇到問題:
下面是我用來生成校驗和的代碼:
unsigned short checksum(unsigned short * buffer, int bytes)
{
unsigned long sum = 0;
unsigned short answer = 0;
int i = bytes;
while(i>0)
{
sum+=*buffer;
buffer+=1;
i-=2;
}
sum = (sum >> 16) + (sum & htonl(0x0000ffff));
sum += (sum >> 16);
return ~sum;
}
此功能適用於 IP 校驗和。
下面是我為我的 TCP 標頭制作的結構:
struct tcp_header
{
unsigned short tcp_sprt;
unsigned short tcp_dprt;
unsigned int tcp_seq;
unsigned int tcp_ack;
unsigned char tcp_res:4;
unsigned char tcp_off:4;
unsigned char tcp_flags;
unsigned short tcp_win;
unsigned short tcp_csum;
unsigned short tcp_urp;
};
我一直在使用 Wireshark 來測試這些數據包,唯一錯誤的是校驗和。
最后,這是我用 TCP 標頭和來自 IP 標頭的信息加載的偽標頭結構:
struct pseudoTcpHeader
{
unsigned int ip_src;
unsigned int ip_dst;
unsigned char zero;//always zero
unsigned char protocol;// = 6;//for tcp
unsigned short tcp_len;
struct tcp_header tcph;
};
一旦我用正確的信息加載了這個結構,我就會在整個偽頭結構上使用校驗和函數,並將 TCP 校驗和分配給該值。 你看到我提供的東西有什么問題嗎? 如果問題不在這里,那可能是我看不到的粗心錯誤。
我在winpcap-users 郵件列表上找到了一個相當不錯的例子,它應該解決 Greg 關於奇數長度數據的評論,並為您提供一些比較您的代碼的內容。
USHORT CheckSum(USHORT *buffer, int size)
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size)
cksum += *(UCHAR*)buffer;
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
我也很難找到計算它的 c++/c 代碼,直到我找到了如何計算 IP/TCP/UDP 校驗和 – 第 2 部分實現 – roman10 ,並且它奏效了! 使用 Wireshark 的驗證對其進行了測試。
更新
鏈接同時中斷,將其恢復並將其作為要點放入我的帳戶 - 如何計算 IP/TCP/UDP 校驗和
我看到了幾件事:
htonl(0x0000ffff)
似乎很可疑。 為什么要將常量轉換為網絡字節順序以將其與主機字節順序中的數據組合?RFC 793說“如果一個段包含奇數個要校驗和的報頭和文本八位字節,最后一個八位字節在右邊用零填充,以形成一個 16 位字,用於校驗和目的。” 您上面的代碼不處理這種情況。 我認為循環條件應該是 i > 1 然后在循環外檢查 i == 1 並對最后一個八位字節進行特殊處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.