Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1170353
  • 博文数量: 115
  • 博客积分: 950
  • 博客等级: 准尉
  • 技术积分: 1734
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-08 20:46
文章分类

全部博文(115)

文章存档

2015年(5)

2014年(28)

2013年(42)

2012年(40)

分类: LINUX

2013-05-16 12:56:28

CheckSum的计算方式可以参考如下代码实现:

点击(此处)折叠或打开

  1. /*
  2.  * Checksum routine for Internet Protocol family headers (C Version)
  3.  */
  4. u_short
  5. in_cksum(u_short *addr, int len)
  6. {
  7.     int nleft = len;
  8.     u_short *w = addr;
  9.     u_short answer;
  10.     int sum = 0;

  11.     /*
  12.      * Our algorithm is simple, using a 32 bit accumulator (sum),
  13.      * we add sequential 16 bit words to it, and at the end, fold
  14.      * back all the carry bits from the top 16 bits into the lower
  15.      * 16 bits.
  16.      */
  17.     while (nleft > 1) {
  18.         sum += *w++;
  19.         nleft -= 2;
  20.     }

  21.     /* mop up an odd byte, if necessary */
  22.     if (nleft == 1)
  23.         sum += *(u_char *)w;

  24.     /*
  25.      * add back carry outs from top 16 bits to low 16 bits
  26.      */
  27.     sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
  28.     sum += (sum >> 16); /* add carry */
  29.     answer = ~sum; /* truncate to 16 bits */
  30.     return (answer);
  31. }

IP/ICMP/TCP/UDP等相关的checksum都可以使用以上函数进行实现。

但是对于不同的数据包,计算checksum的数据段范围还是有所不同的。

ps:
 在计算checksum之间:
首先把checksum字段置为0
其次计算checksum获取结果
最后如果计算后的checksum为0,则置checksum字段为0xffff。

IP CheckSum:
  只包含Ip Header 20个字节

ICMP CheckSum:
  包含Icmp Header(8个字节)  + Icmp Data (n个字节)。

对于TCP/UDP的CheckSum,需要包含一个伪Ip Header。
所以TCP/UDP的checksum:
  包含伪ip header (12个字节) + header (udp 8个字节, tcp 20个字节) + data(n个字节)

udp的checksum是可选的,但是一般都会进行计算。
以udp为例,以下是udp header:

加上udp的伪ip header:


tcp的也是类似,只是tcp的header和udp的header有所不同。



在计算udp/tcp的checksum时候,因为需要构建ip的伪头部,所以也就需要实现一个带udp/tcp伪头部的udp/tcp header结构:

点击(此处)折叠或打开

  1. struct udpiphdr {
  2.     struct ipovly ui_i; /* overlaid ip structure */
  3.     struct udphdr ui_u; /* udp header */
  4. };
  5. #define ui_next ui_i.ih_next
  6. #define ui_prev ui_i.ih_prev
  7. #define ui_x1 ui_i.ih_x1
  8. #define ui_pr ui_i.ih_pr
  9. #define ui_len ui_i.ih_len
  10. #define ui_src ui_i.ih_src
  11. #define ui_dst ui_i.ih_dst
  12. #define ui_sport ui_u.uh_sport
  13. #define ui_dport ui_u.uh_dport
  14. #define ui_ulen ui_u.uh_ulen
  15. #define ui_sum ui_u.uh_sum


  16. /*
  17.  * Overlay for ip header used by other protocols (tcp, udp).
  18.  */
  19. struct ipovly {
  20.     caddr_t ih_next, ih_prev; /* for protocol sequence q's */
  21.     u_char ih_x1; /* (unused) */
  22.     u_char ih_pr; /* protocol */
  23.     short ih_len; /* protocol length */
  24.     struct in_addr ih_src; /* source internet address */
  25.     struct in_addr ih_dst; /* destination internet address */
  26. };


阅读(11193) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~