IP資料包的校驗和演算法_儒雅
導讀:
本文轉自
http://hi.baidu.com/zengzhaonong/blog/item/c933102403bc1530c89559fb.html
在傳送資料時,為了計算數IP據報的校驗和。應該按如下步驟: (1) 把IP資料包的校驗和欄位置為0。 (2) 把首部看成以16位為單位的數字組成,依次進行二進位制反碼求和 (3) 把得到的結果存入校驗和欄位中。 在接收資料時,計算資料包的校驗和相對簡單,按如下步驟: (1)把首部看成以16位為單位的數字組成,依次進行二進位制反碼求和,包括校驗和欄位。 (2)檢查計算出的校驗和的結果是否等於零。 (3)如果等於零,說明被整除,校驗是和正確。否則,校驗和就是錯誤的,協議棧要拋棄這個資料包。 Linux 2.6核心中的校驗演算法,使用匯編語言編寫的,顯然效率要高些 /usr/src/linux-2.6.23/include/asm-i386/checksum.h static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { unsigned int sum; __asm__ __volatile__( "movl (%1), %0 -;/n" "subl $4, %2 -;/n" "jbe 2f ;/n" "addl 4(%1), %0 ;/n" "adcl 8(%1), %0 ;/n" "adcl 12(%1),%0 ;/n" "1: adcl 16(%1), %0 ;/n" "lea 4(%1), %1 -;/n" "decl %2 ;/n" "jne 1b -;/n" "adcl $0, %0 ;/n" "movl %0, %2 ;/n" "shrl $16, %0 ;/n" "addw %w2, %w0 -;/n" "adcl $0, %0 ;/n" "notl %0 ;/n" "2: ;/n" : "=r" (sum), "=r" (iph), "=r" (ihl) : "1" (iph), "2" (ihl) : "memory"); return (__force __sum16)sum; } (1) 將IP頭部(包括可選項)以32位為單位進行進位加法運算 (2) 將sum的低16位和高16位相加 (3) 取反 1b -- 1 before 在這個函式中,第一個引數顯然就是IP資料包的首地址,所有演算法幾乎一樣。需要注意的是第二個引數,它是直接使用IP資料包頭資訊中的首部長度欄位,不需要進行轉換,因此,速度又快了(高手就是考慮的周到) 第二種演算法就非常普通了,是用C語言編寫的。許多實現網路協議棧的程式碼,這個演算法是最常用的了,即使變化,也無非是先取反後取和之類的。考慮其原因,估計還是C語言的移植性更好吧。下面是該函式的實現: unsigned short checksum(unsigned short *buf, int nword) { unsigned long sum; for(sum = 0; nword > 0; nword--) sum += *buf++; sum = (sum>>16) + (sum&0xffff); sum += (sum>>16); return ~sum; } 讓我們假設一個IP頭資料,來解cksum的惑 IP頭資料: 01000101 /*ver_hlen*/ 00000000 /*tos*/ 00000000 00000010 /*len*/ 00000000 00000000 /*id*/ 00000000 00000000 /*offset*/ 00000100 /*ttl*/ 00010001 /*type*/ 00000000 00000000 /*cksum(0)*/ 01111111 00000000 00000000 00000001 -/*sip*/ 01111111 00000000 00000000 00000001 -/*dip*/ 運算過程(注意是大端格式加): for(sum = 0; nword > 0; nword--) sum += *buf++; -01000101 00000000 -00000000 00000010 --------------------- -01000101 00000010 -00000000 00000000 --------------------- -01000101 00000010 -00000000 00000000 --------------------- -01000101 00000010 -00000100 00010001 --------------------- -01001001 00010011 -00000000 00000000 --------------------- -01001001 00010011 -01111111 00000000 --------------------- -11001000 00010011 -00000000 00000001 --------------------- -11001000 00010100 -01111111 00000000 --------------------- 101000111 00010100 -00000000 00000001 --------------------- 101000111 00010101 sum sum = (sum>>16) + (sum&0xffff); 00000000 00000001 (sum>>16) 01000111 00010101 (sum&0xffff) --------------------- 01000111 00010110 sum += (sum>>16); 01000111 00010110 00000000 00000000 (sum>>16) --------------------- 01000111 00010110 sum ~sum 10111000 11101001 cksum 說白了就是迴圈加,然後在取反! 對方機器呼叫checksum()計算校驗和,如果校驗和為0表明IP包傳輸正確 ----------------------------------------------------------- 01000101 /*ver_hlen*/ 00000000 /*tos*/ 00000000 00000010 /*len*/ 00000000 00000000 /*id*/ 00000000 00000000 /*offset*/ 00000100 /*ttl*/ 00010001 /*type*/ 10111000 11101001 /*cksum(0)*/ 01111111 00000000 00000000 00000001 /*sip*/ 01111111 00000000 00000000 00000001 /*dip*/ -01000101 00000000 -00000000 00000010 --------------------- -01000101 00000010 -00000000 00000000 --------------------- -01000101 00000010 -00000000 00000000 --------------------- -01000101 00000010 -00000100 00010001 --------------------- -01001001 00010011 -10111000 11101001 --------------------- 100000001 11111100 -01111111 00000000 --------------------- 110000000 11111100 -00000000 00000001 --------------------- 110000000 11111101 -01111111 00000000 --------------------- 111111111 11111101 -00000000 00000001 --------------------- 111111111 11111110 sum sum = (sum>>16) + (sum&0xffff); 00000000 00000001 (sum>>16) 11111111 11111110 (sum&0xffff) ---------------------- 11111111 11111111 sum += (sum>>16); 11111111 11111111 00000000 00000000 (sum>>16) ---------------------- 11111111 11111111 ~sum 00000000 00000000 |
本文轉自
http://hi.baidu.com/zengzhaonong/blog/item/c933102403bc1530c89559fb.html
相關文章
- IP 資料包
- rpm包的校驗和檔案讀取
- 資料校驗
- MySQL手動資料校驗+雲資料庫資料校驗MySql資料庫
- IP和TCP抓包分析實驗TCP
- 整理SQL SERVER資料頁checksum校驗演算法SQLServer演算法
- [資料校驗/資料質量] 資料校驗框架(Java):hibernate-validation框架Java
- easypoi資料校驗
- 行式填報 資料校驗 --- 小計校驗
- Binding(四):資料校驗
- ORACLE資料校驗文件Oracle
- Go IP 段範圍校驗Go
- IP資料包格式詳解
- struts2資料校驗
- JSR303 資料校驗JS
- Hibernate資料校驗簡介
- 前端資料校驗後,後端介面是否需要再次校驗?前端後端
- 《計算機網路微課堂》實驗11 IP資料包的傳送和轉發流程計算機網路
- IP資料包頭部資訊分析
- 前端與後端TP的資料校驗前端後端
- IpAddressService ip地址引數校驗 allIpAddressCheck分析iPad
- SAP ABAP maintanence view的資料校驗機制AIView
- .NET Attribute在資料校驗上的應用
- 前端資料校驗從建模開始前端
- 使用spring validation 作為資料校驗Spring
- openGauss-資料校驗gs_datacheck
- TCP的校驗和與編號TCP
- .NET中特性+反射 實現資料校驗反射
- 使用@Validated校驗List集合中資料失效
- WPF 資料繫結之ValidationRule資料校驗綜合Demo
- 校驗和與編號
- 『學了就忘』Linux軟體包管理 — 43、RPM包的校驗和證書Linux
- 2.4 一種基於kafka增量資料校驗的方案Kafka
- Node 在 Controller 層如何進行資料校驗Controller
- 深入Spring官網系列(十七):Java資料校驗SpringJava
- vxe-form table 表單使用資料校驗ORM
- 資料庫 校驗名稱唯一性,用於新增和修改功能資料庫
- Bumpover.js – 牢固而趁手的資料校驗轉換庫JS
- 獵豹網校資料結構與演算法資料結構演算法