加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

boost-asio – 使用Asio Boost的ICMPv6的校验和计算问题

发布时间:2020-12-16 07:04:39 所属栏目:百科 来源:网络整理
导读:我使用ASIO文档中提供的ICMP example来创建一个简单的ping实用程序.但是,该示例仅涵盖IPv4,我很难将其与IPv6配合使用. 升级ICMP标头类以支持IPv6需要稍作更改 – ICMP和ICMPv6标头之间的唯一区别是ICMP类型的不同枚举.但是,我在计算需要包含在ICMPv6标头中的
我使用ASIO文档中提供的ICMP example来创建一个简单的ping实用程序.但是,该示例仅涵盖IPv4,我很难将其与IPv6配合使用.

升级ICMP标头类以支持IPv6需要稍作更改 – ICMP和ICMPv6标头之间的唯一区别是ICMP类型的不同枚举.但是,我在计算需要包含在ICMPv6标头中的校验和时遇到问题.

对于IPv4,校验和基于ICMP报头和有效负载.但是,对于IPv6,校验和应包括ICMPv6报头和有效负载之前的IPv6伪报头. ICMPv6校验和功能需要知道IPv6头中的源和目标地址.但是,我们无法控制进入IPv6标头的内容.怎么能在Asio-Boost中完成?

有关参考,请参阅下面的IPv4校验和计算功能.

void compute_checksum(icmp_header& header,Iterator body_begin,Iterator body_end)
{
  unsigned int sum = (header.type() << 8) + header.code()
    + header.identifier() + header.sequence_number();

  Iterator body_iter = body_begin;
  while (body_iter != body_end)
  {
    sum += (static_cast<unsigned char>(*body_iter++) << 8);
    if (body_iter != body_end)
    sum += static_cast<unsigned char>(*body_iter++);
  }

  sum = (sum >> 16) + (sum & 0xFFFF);
  sum += (sum >> 16);
  header.checksum(static_cast<unsigned short>(~sum));
}

[编辑]

如果校验和计算不正确会有什么后果?如果echo请求的校验和无效,目标主机是否会发送echo reply?

解决方法

如果校验和不正确,典型的IPv6实现将丢弃数据包.所以,这是一个严重的问题.

如果你坚持自己制作包,你就必须这样做
完全.这包括找到源IP地址,将其放入
计算校验和之前的伪标头.我就是这样做的
在C中,通过调用connect()作为我的目标地址
(即使我使用UDP,所以它应该适用于ICMP):

/* Get the source IP addresse chosen by the system (for verbose display,and 
     * for checksumming) */
    if (connect(sd,destination->ai_addr,destination->ai_addrlen) < 0) {
        fprintf(stderr,"Cannot connect the socket: %sn",strerror(errno));
        abort();
    }
    source = malloc(sizeof(struct addrinfo));
    source->ai_addr = malloc(sizeof(struct sockaddr_storage));
    source_len = sizeof(struct sockaddr_storage);
    if (getsockname(sd,source->ai_addr,&source_len) < 0) {
        fprintf(stderr,"Cannot getsockname: %sn",strerror(errno));
        abort();
    }

然后,后来:

sockaddr6 = (struct sockaddr_in6 *) source->ai_addr;
        op6.ip.ip6_src = sockaddr6->sin6_addr;

和:

op6.udp.check =
            checksum6(op6.ip,op6.udp,(u_int8_t *) & message,messagesize);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读