隧道数据包的UDP校验和失败

隧道数据包的UDP校验和失败,udp,wireshark,checksum,Udp,Wireshark,Checksum,我正在生成GTP隧道包,格式如下: “外部IP”->“外部UDP”->“GTP”->“内部IP”->“内部UDP” 我使用的UDP校验和算法实际上来自DHCPd **********************code snippet start ********************** udp_header->check = wrapsum(in_cksum((unsigned char *)udp_header, sizeof(struct udp_header),

我正在生成GTP隧道包,格式如下:

“外部IP”->“外部UDP”->“GTP”->“内部IP”->“内部UDP”

我使用的UDP校验和算法实际上来自DHCPd

**********************code snippet start **********************
udp_header->check = wrapsum(in_cksum((unsigned char *)udp_header, sizeof(struct udp_header),
                                       in_cksum((unsigned char *)&buffer[i], send_len-i,
                        in_cksum((unsigned char *)&ip_header->saddr,
                             2*sizeof(ip_header->saddr),
                             IPPROTO_UDP + ntohs(udp_header->len)))));

/* ******************************************* */

/*
 * Checksum routine for Internet Protocol family headers (C Version)
 *
 * Borrowed from DHCPd
 */

static u_int32_t in_cksum(unsigned char *buf,
              unsigned nbytes, u_int32_t sum) {
  uint i;

  /* Checksum all the pairs of bytes first... */
  for (i = 0; i < (nbytes & ~1U); i += 2) {
    sum += (u_int16_t) ntohs(*((u_int16_t *)(buf + i)));
    /* Add carry. */
    if(sum > 0xFFFF)
      sum -= 0xFFFF;
  }

  /* If there's a single byte left over, checksum it, too.   Network
     byte order is big-endian, so the remaining byte is the high byte. */
  if(i < nbytes) {
#ifdef DEBUG_CHECKSUM_VERBOSE
    debug ("sum = %x", sum);
#endif
    sum += buf [i] << 8;
    /* Add carry. */
    if(sum > 0xFFFF)
      sum -= 0xFFFF;
  }

  return sum;
}

/* ******************************************* */

static u_int32_t wrapsum (u_int32_t sum) {
  sum = ~sum & 0xFFFF;
  return htons(sum);
}


**********************code snippet end**********************
*******************代码段开始**********************
udp_头->检查=wrapsum(在_cksum((无符号字符*)udp_头中,sizeof(结构udp_头),
在校验和((无符号字符*)和缓冲区[i]中,发送校验列-i,
在_cksum((无符号字符*)&ip_头->saddr中,
2*sizeof(ip_头->SADD),
IPPROTO_UDP+ntohs(UDP_头->len‘‘‘‘)’);
/* ******************************************* */
/*
*Internet协议系列头的校验和例程(C版本)
*
*从DHCPd借来
*/
静态u_int32_t in_cksum(无符号字符*buf,
无符号N字节,u_int32_t总和){
uint i;
/*首先对所有字节对进行校验和*/
对于(i=0;i<(n字节&~1U);i+=2){
sum+=(u_int16_t)ntohs(*(u_int16_t*)(buf+i));
/*加上进位*/
如果(总和>0xFFFF)
总和-=0xFFFF;
}
/*如果只剩下一个字节,也对其进行校验和。网络
字节顺序是big-endian,因此剩余的字节是高位字节*/
if(i
外部UDP调用和内部UDP调用都使用相同的校验和函数。然而,我的内部UDP很好,但我的外部UDP未通过wireshark的校验和检查。有人对这个问题有什么建议吗