會合併一起寫主要原因是這兩種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 意見:
張貼留言