日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ip校验和及udp校验和的计算方法

發布時間:2023/12/4 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ip校验和及udp校验和的计算方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、ip校驗和的計算:?
計算方法:?
1. ip包頭(共20個字節)按照每16個bit作為一個值依次進行相加?
2. 將計算結果的進位加到低16位上?
3. 將結果取反?
ip包頭的內存內容?
eg:?
45 00 00 20 0F B8 00 00?
80 11 00 00 C0 A8 0A 9F?
C0 A8 0A C7

將 0x4500 0x0020 0x0FB8 0x0000 0x8011 0x0000 0xC0A8 0x0A9F 0xC0A8 0x0AC7 依次相加 所得結果為0x26B9F 然后將 0x0002 + 0x6B9F = 0x6BA1?
然后將 0x6BA1 取反得 0x945E

要注意兩點:

1 在給ip_header計算校驗和之前 首先把ip_header的checksum字段置為0 2 計算得到checksum之后 賦值時要轉換為網絡字節序:ip_header.checksum = htons(checksum); struct ip_header //小端模式__LITTLE_ENDIAN { unsigned char ihl:4; //ip header length unsigned char version:4; //version u_char tos; //type of service u_short tot_len; //total length u_short id; //identification u_short frag_off; //fragment offset u_char ttl; //time to live u_char protocol; //protocol type u_short check; //check sum u_int saddr; //source address u_int daddr; //destination address }; // 計算ip數據包的checksum // 將20個字節的ip數據包每16位組成一個字 依次相加 設所得結果為 0x34ACE // 將 進位的3與 0x4ACE相加 得 0x4AD1 // 將 0x4AD1取反得到checksum u_short get_ip_checksum(char* ip_hdr) {char* ptr_data = ip_hdr; u_long tmp = 0; u_long sum = 0; for (int i=0; i<20; i+=2){tmp += (u_char)ptr_data[i] << 8; tmp += (u_char)ptr_data[i+1]; sum += tmp; tmp = 0; }u_short lWord = sum & 0x0000FFFF; u_short hWord = sum >> 16; u_short checksum = lWord + hWord; checksum = ~checksum; return checksum; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

二、udp校驗和

// udp的checksum計算是用到的結構體 // udp中, 參與計算checksum的數據包括三部分: 亞頭部 + UDP頭部 + 數據部分 // 亞頭部: 4 byte源ip地址 + 4 byte目的ip地址 + 0x00 + 1 byte協議 + UDP 長度(2byte)(udp包頭長度+數據長度) // UDP包頭: 2 byte源端口 + 2 byte目的端口 + 2 byte UDP包長(此處是udp包頭自帶的值不用變) + 0x0000 (checksum) // 數據部分 // 計算方法同get_ip_checksum一樣 typedef struct udp_check_subhdr // udp計算checksum時的 亞頭部: 4 byte源ip地址 + 4 byte目的ip地址 + 0x00 + 1 byte協議 + UDP 長度(2byte) {u_long src_ip; u_long dst_ip; char mbz; // must be zerochar protocol; u_short len; // 這里的長度是指 udp packet中 udp頭部和數據部分的總長度 } udp_check_subhdr;// pudp_pkt: udp的整個packet // pkt_len: 整個packet的長度(以太網數據幀頭 ip頭 udp頭) u_short get_udp_checksum(char* pudp_pkt, int pkt_len) {ether_header *eth_hdr = (ether_header *)pudp_pkt; ip_header *ip_hdr = (ip_header*)( pudp_pkt+sizeof(ether_header) ); udphdr *udp_hdr = (udphdr*)( (char*)ip_hdr+sizeof(ip_header) ); u_short udp_part_len = pkt_len-sizeof(ether_header)-sizeof(ip_header); // 亞包頭中的len: =udp包頭長度+數據長度(udp包總長度-ethernet包頭長度-ip包頭長度); udp_check_subhdr udp_subhdr; udp_subhdr.protocol = ip_hdr->protocol; udp_subhdr.dst_ip = ip_hdr->daddr; udp_subhdr.src_ip = ip_hdr->saddr; udp_subhdr.mbz = 0x00; udp_subhdr.len = htons(udp_part_len); int subhdr_len = sizeof(udp_check_subhdr); int buf_size = udp_part_len + subhdr_len; // 亞包頭 + udp包頭 + 數據部分的總長度if (pkt_len < buf_size)return 0; u_char* buffer = (u_char*)malloc(buf_size); memset(buffer, 0x00, buf_size); memcpy(buffer, (char*)&udp_subhdr, subhdr_len); memcpy(buffer + subhdr_len, (char*)udp_hdr, udp_part_len); unsigned char* ptr_data = buffer; u_long tmp = 0; u_long sum = 0; for (int i=0; i<buf_size; i+=2){tmp += (u_char)ptr_data[i] << 8; tmp += (u_char)ptr_data[i+1]; sum += tmp; tmp = 0; }u_short lWord = sum & 0x0000FFFF; u_short hWord = sum >> 16; u_short checksum = lWord + hWord; checksum = ~checksum; return checksum; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

最后:?ip校驗和還有udp校驗和的查看是在接收端查看的,從源端查看是沒有計算的值(ip校驗和是0x00 udp校驗和不清楚什么意義) 用pcap發送自定義數據包時 調用pcap_sendpacket時是直接發送定義好的數據包 就是將定義好的包直接通過網卡發送 不會經過電腦上的ip層和鏈路層 所以 校驗和要自己計算

從兩個網頁處學到計算方法:?
http://www.360doc.com/content/12/0511/15/621500_210332306.shtml?
http://blog.csdn.net/maeom/article/details/6065203

*注: 僅作為筆記之用 如有錯誤或不妥之處還望指正。

總結

以上是生活随笔為你收集整理的ip校验和及udp校验和的计算方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。