tcp 偽頭部 結構 格式 校驗和
//tcp 偽頭部, 計算校驗和時需要
typedef struct
{
unsigned long saddr; //源IP地址
unsigned long daddr; //目的IP地址
char mbz; // mbz = must be zero, 用於填充對齊
char protocal; //8位協議號
unsigned short tcpl; // TCP包長度
}psdheader_t;
TCP頭校驗和計算演算法詳解
2010-06-23 08:02:24| 分類: 程式設計 | 標籤: |字號大中小 訂閱
我就不管是按“位”(bit)取反相加,還是按“1的補碼”相加了,總之
就是把需要進行校驗的“字串”加(+)起來,把這相加的結果取反當做
“校驗和” (Checksum),比如,相加的結果是0101,那麼“校驗和”就
是1010,驗證的時候呢,就是 0101+1010 = 1111 ,取反後,就是0
——如果驗證得“零”(0),就是正確的!
先將checksum欄位置零,然後按16位分組,計算2進位制反碼和,最後再求和的反碼!
為了計算一份資料包的IP檢驗和,首先把檢驗和欄位置為0。然後,對首部中每個16bit進行二進位制反碼求和(整個首部看成是由一串16bit的字組成),結果存在檢驗和欄位中。當收到一份IP資料包後,同樣對首部中每個16bit進行二進位制反碼的求和。由於接收方在計算過程中包含了傳送方存在首部中的檢驗和,因此,如果首部在傳輸過程中沒有發生任何差錯,那麼接收方計算的結果應該為全1。如果結果不是全1(即檢驗和錯誤),那麼IP就丟棄收到的資料包。但是不生成差錯報文,由上層去發現丟失的資料包並進行重傳。
當傳送IP包時,需要計算IP報頭的校驗和:
1、 把校驗和欄位置為0;
2、 對IP頭部中的每16bit進行二進位制求和;
3、 如果和的高16bit不為0,則將和的高16bit和低16bit反覆相加,直到和的高16bit為0,從而獲得一個16bit的值;
4、 將該16bit的值取反,存入校驗和欄位。
◆當接收IP包時,需要對報頭進行確認,檢查IP頭是否有誤,演算法同上2、3步,然後判斷取反的結果是否為0,是則正確,否則有錯。
演算法:
SHORT 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); //將高16bit與低16bit相加
cksum += (cksum>>16); //將進位到高位的16bit與低16bit 再相加
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));
typedef struct
{
unsigned long saddr; //源IP地址
unsigned long daddr; //目的IP地址
char mbz; // mbz = must be zero, 用於填充對齊
char protocal; //8位協議號
unsigned short tcpl; // TCP包長度
}psdheader_t;
TCP頭校驗和計算演算法詳解
2010-06-23 08:02:24| 分類: 程式設計 | 標籤: |字號大中小 訂閱
我就不管是按“位”(bit)取反相加,還是按“1的補碼”相加了,總之
就是把需要進行校驗的“字串”加(+)起來,把這相加的結果取反當做
“校驗和” (Checksum),比如,相加的結果是0101,那麼“校驗和”就
是1010,驗證的時候呢,就是 0101+1010 = 1111 ,取反後,就是0
——如果驗證得“零”(0),就是正確的!
先將checksum欄位置零,然後按16位分組,計算2進位制反碼和,最後再求和的反碼!
為了計算一份資料包的IP檢驗和,首先把檢驗和欄位置為0。然後,對首部中每個16bit進行二進位制反碼求和(整個首部看成是由一串16bit的字組成),結果存在檢驗和欄位中。當收到一份IP資料包後,同樣對首部中每個16bit進行二進位制反碼的求和。由於接收方在計算過程中包含了傳送方存在首部中的檢驗和,因此,如果首部在傳輸過程中沒有發生任何差錯,那麼接收方計算的結果應該為全1。如果結果不是全1(即檢驗和錯誤),那麼IP就丟棄收到的資料包。但是不生成差錯報文,由上層去發現丟失的資料包並進行重傳。
當傳送IP包時,需要計算IP報頭的校驗和:
1、 把校驗和欄位置為0;
2、 對IP頭部中的每16bit進行二進位制求和;
3、 如果和的高16bit不為0,則將和的高16bit和低16bit反覆相加,直到和的高16bit為0,從而獲得一個16bit的值;
4、 將該16bit的值取反,存入校驗和欄位。
◆當接收IP包時,需要對報頭進行確認,檢查IP頭是否有誤,演算法同上2、3步,然後判斷取反的結果是否為0,是則正確,否則有錯。
演算法:
SHORT 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); //將高16bit與低16bit相加
cksum += (cksum>>16); //將進位到高位的16bit與低16bit 再相加
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));
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25897606/viewspace-704311/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- TCP頭部TCP
- TCP的校驗和與編號TCP
- ICMP 頭部資料結構 (轉)資料結構
- 使用wireshark分析TCP/IP協議中TCP包頭的格式TCP協議
- 校驗碼-體系結構-指令-流水線
- Django csrf跨站請求偽造,校驗,CBV忽略與允許csrf校驗Django
- 好久沒發貼,貼個tip:PE 頭部校驗和(checksum)的計算 (3千字)
- 解析SQL SERVER 資料頁面頭部結構SQLServer
- 計算機網路王道考研-TCP的特點和TCP首部格式總結計算機網路TCP
- 格式校驗利器:JSON Schema 簡介JSON
- 巧用偽元素和偽類讓我們的html結構更清晰合理HTML
- Gin(四):表單提交校驗和模型繫結模型
- [經驗]TCP,UDP完整資料包校驗和通用計算 - 日誌 - redice - 我的空間TCPUDP
- 偽元素和偽類的區別總結
- IP校驗和詳解
- 校驗和與編號
- OpenGL ES 實現頭部形變和頭部晃動效果
- redis 資料結構和內部編碼Redis資料結構
- @Validated和@Valid的區別?校驗級聯屬性(內部類)
- 理解 TCP(二):報文結構TCP
- TCP 請求頭TCP
- 用WPS格式轉換工具校驗身份證號碼
- tcp和udp使用總結TCPUDP
- HttpRunner 的結果校驗器優化HTTP優化
- 論MVVM偽框架結構和MVC中M的實現機制MVVM框架MVC
- springMVC:校驗框架:多規則校驗,巢狀校驗,分組校驗;ssm整合技術SpringMVC框架巢狀SSM
- IP和TCP抓包分析實驗TCP
- haipproxy核心校驗和排程策略AI
- LoadRunner內部結構
- 索引內部結構探索索引
- undo 事物內部結構
- DATA BLOCK內部結構BloC
- 基於jquery+html開發的json格式校驗工具jQueryHTMLJSON
- TCP/IP、HTTP和Socket總結TCPHTTP
- 普通人的校招經驗總結
- 偽類和偽元素
- 在TCP三次握手後插入偽造的TCP包(轉)TCP
- 總結偽類與偽元素