TCP/IP笔记二:IP头部/UDP/TCP校验和的计算

The IP checksum is the 16 bit one's complement of the one's complement sum of all 16 bit words in the header.

“1的补码”即反码。

IP只对首部而不对数据部分计算校验和,计算方法是将首部视为16位整数的序列,对首部所有16位整数各求反码,并将结果相加,再对求得的和计算一次二进制反码。

计算机是用二进制补码来表示整数的,下面是等价的算法。

下面以UDP计算伪头部校验和的函数为例:

/*------------------------------------------------------------------------
 *  udpcksum -  compute a UDP pseudo-header checksum
 *------------------------------------------------------------------------
 */
unsigned short
udpcksum(struct ep *pep, int len)
{
	struct	ip	*pip = (struct ip *)pep->ep_data;
	struct	udp	*pudp = (struct udp *)pip->ip_data;
	unsigned	short	*sptr;
	unsigned	long ucksum;
	int		i;

	ucksum = 0;

	sptr = (unsigned short *) &pip->ip_src;
	/* 2*IP_ALEN octets = IP_ALEN shorts... */
	/* they are in net order.		*/
	for (i=0; i<IP_ALEN; ++i)
		ucksum += *sptr++;
	sptr = (unsigned short *)pudp;
	ucksum += hs2net(IPT_UDP + len);
	if (len % 2) {
		((char *)pudp)[len] = 0;	/* pad */
		len += 1;	/* for the following division */
	}
	len >>= 1;	/* convert to length in shorts */

	for (i=0; i<len; ++i)
		ucksum += *sptr++;
	ucksum = (ucksum >> 16) + (ucksum & 0xffff);
	ucksum += (ucksum >> 16);

	return (short)(~ucksum & 0xffff);
}

其余校验和的算法是类似的。


Linux中用汇编语言加速校验和计算的代码:

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"
	/* Since the input registers which are loaded with iph and ihl
	   are modified, we must also specify them as outputs, or gcc
	   will assume they contain their original values. */
		     : "=r" (sum), "=r" (iph), "=r" (ihl)
		     : "1" (iph), "2" (ihl)
		     : "memory");
	return (__force __sum16)sum;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值