If the checksum is incorrect, a typical IPv6 implementation will output the packet. So this is a serious problem.
If you insist on developing the package yourself, you will have to do it completely. This involves finding the source IP address, a pseudo-header, before calculating the checksum. Here's how I do it in C, calling connect () for my assigned destination address (even when I use UDP, so it should work for ICMP):
if (connect(sd, destination->ai_addr, destination->ai_addrlen) < 0) { fprintf(stderr, "Cannot connect the socket: %s\n", 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: %s\n", strerror(errno)); abort(); }
then later:
sockaddr6 = (struct sockaddr_in6 *) source->ai_addr; op6.ip.ip6_src = sockaddr6->sin6_addr;
and
op6.udp.check = checksum6(op6.ip, op6.udp, (u_int8_t *) & message, messagesize);
source share