IP和TCP包頭校驗和計算方法

IP和TCP包頭校驗和計算方法

校驗和的算法:

          將數據以字爲單位累加到一個雙字中,如果數據長度爲奇數,最後一個字節要先變成字,然後在加到原來的雙字中,最後得到的結果是一個雙字,最後將這個雙字的高16位和低16位反覆相加,直到高16位爲0,從而就獲得一個16位的值,再將這個16位的值取反就得到校驗和的值了。

在接收端接收到IP數據包後,要對IP頭進行檢查看是否有誤,所用的算法與上面一致,不同的是最終的結果要爲0。

程序如下:

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);

}

實例:

IP頭:  

              45 00    00 31

              89 F5    00 00

              6E 06   00 00(校驗字段)

              DE B7   45 5D       ->    222.183.69.93

              C0 A8   00 DC     ->    192.168.0.220

計算:   

     4500 0031 89F5 0000 6e06 0000 DEB7 455D C0A8 00DC =3 22C4

     0003 22C4 = 22C7

     ~22C7 = DD38      ->即爲應填充的校驗和

當接受到IP數據包時,要檢查IP頭是否正確,則對IP頭進行檢驗,方法同上:

計算:

    4500 0031 89F5 0000 6E06 DD38 DEB7 455D C0A8 00DC =3 FFFC

    0003 FFFC = FFFF

     ~FFFF = 00000     ->正確

TCP首部檢驗和與IP首部校驗和的計算方法基本相同,在程序中使用同一個函數來計算。

需要注意的是,由於TCP首部中不包含源地址與目標地址等信息,爲了保證TCP校驗的有效性,在進行TCP校驗和的計算時,需要增加一個TCP僞首部的校驗和,定義如下:

struct

{

unsigned long saddr; //源地址

unsigned long daddr; //目的地址

char mbz;//置空

char ptcl; //協議類型

unsigned short tcpl; //TCP長度

}psd_header;

然後我們將這兩個字段複製到同一個緩衝區SendBuf中並計算TCP校驗和:

memcpy(SendBuf,&psd_header,sizeof(psd_header));

memcpy(SendBuf sizeof(psd_header),&tcp_header,sizeof(tcp_header));

tcp_header.th_sum=checksum((USHORT *)SendBuf,sizeof(psd_header) sizeof(tcp_header));


uip裏通過if(uip_ipchksum() != 0xffff)來判斷是否校驗成功,當爲oxffff時,校驗成功


原文轉自:http://hi.baidu.com/xinjf/item/8f046ed95b762e3549e1dd19

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章