會合併一起寫主要原因是這兩種Protocol在計算checksum時,有共同點,都需要Pseudo Header,且虛擬標頭的欄位都相同。
這寫法只需要兩個參數,一個是IP標頭,一個是UDP或TCP的標頭。大部分我寫法是把TCP和UDP分開,或是把DIP/SIP當作參數,不過後來想想TCP/UDP一定包含IP,且IP裡頭一定有DIP/SIP,若是自己填可能還會錯,最後就合併成這兩個參數就好,其他值都可以從這裡頭拿。
程式碼如下:
typedef std::vector <unsigned char> Bytes;
unsigned short tcpudpchksum_calc(Bytes iphdr, Bytes tcpudphdr)
{
unsigned short protocol = iphdr[9];//6-TCP, 17-UDP
unsigned short padd=0;
unsigned short word16;
unsigned int sum;
// Protocol長度,虛擬標頭要用到
int prot_len;
if(protocol == 17)//UDP只看header length
prot_len = tcpudphdr[4]*16+tcpudphdr[5];
else if(protocol == 6)//TCP看total length
prot_len = tcpudphdr.size();
if (prot_len%2 == 1){
padd=1;
tcpudphdr.push_back(0);//奇數補0成偶數bytes
}
sum=0;
// 每2個byte加總
for (int i=0; i>16)
sum = (sum & 0xFFFF)+(sum >> 16);
// 最後取1的補數
sum = ~sum;
return ((unsigned short) sum);
}
引用的時候,記得先把TCP/UDP標頭裡的checksum給清0,才不會算出奇怪值啊。
0 意見:
張貼留言