我的程序应该发送UDP数据报,使用Raw套接字用于IPv6协议 .

我必须在套接字选项中使用 IPV6 CHECKSUM . 代码编译得很好,但是TCPDump的长度很差 .

IP6 fe80 :: 20c:29ff:fe95:c051.24576> waw02s13-in-x03.1e100.net.0:UDP,坏长度12280> 40

我错过了什么或我做错了什么?

int main(int argc, char** argv) {

    int                     sockfd; 
    int                     offset; 
    int                     retval; 

    struct addrinfo         hints;
    struct addrinfo         *rp, *result;

    unsigned char           datagram[sizeof(struct ip6_hdr) + sizeof(struct udphdr)
                                     ] = {0};

    struct ip6_hdr              *ip_header      = (struct ip6_hdr *)datagram;

    struct udphdr           *udp_header     = (struct udphdr *)
            (datagram + sizeof(struct ip6_hdr));

    if (argc != 3) {
        fprintf(
            stderr,
            "Invocation: %s <HOSTNAME OR IP ADDRESS> <PORT>\n",
            argv[0]
        );

        exit(EXIT_FAILURE);
    }

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family         =       AF_INET6; 
    hints.ai_socktype       =       SOCK_RAW; 
    hints.ai_protocol       =       IPPROTO_UDP; 


    retval = getaddrinfo(argv[1], NULL, &hints, &result);
    if (retval != 0) {
        fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(retval));
        exit(EXIT_FAILURE);
    }

    offset = 6;

    for (rp = result; rp != NULL; rp = rp->ai_next) {

        sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        if (sockfd == -1) {
            perror("socket()");
            continue;
        }

        retval = setsockopt(
                     sockfd,
                     IPPROTO_IPV6, IPV6_CHECKSUM,
                     &offset, sizeof(offset)
                 );

        if (retval == -1) {
            perror("setsockopt()");
            exit(EXIT_FAILURE);
        } else {
            break;
        }
    }

    if (rp == NULL) {
        fprintf(stderr, "Client failure: could not create socket.\n");
        exit(EXIT_FAILURE);
    }

    ip_header->ip6_flow            =       htonl((6 << 28) | (0 << 20) | 0);
    ip_header->ip6_hops            =       255;
    ip_header->ip6_nxt             =       IPPROTO_UDP;
    ip_header->ip6_plen            =       sizeof(struct ip6_hdr)
                                           + sizeof(struct udphdr);

    inet_pton(AF_INET6, SOURCE_ADDRESS, &(ip_header->ip6_src));
    inet_pton(AF_INET6, argv[1], &(ip_header->ip6_dst));


    udp_header->uh_sport            =       htons(SOURCE_PORT);
    udp_header->uh_dport            =       htons(atoi(argv[2]));
    udp_header->uh_ulen             =       htons(ip_header->ip6_plen);


    fprintf(stdout, "Sending UDP...\n");

    for (;;) {
        retval = sendto(
                     sockfd,
                     datagram, ip_header->ip6_plen,
                     0,
                     rp->ai_addr, rp->ai_addrlen
                 );

        if (retval == -1) {
            perror("sendto()");
        }

        sleep(1);
    }

    exit(EXIT_SUCCESS);
}

Wireshark Image

有任何想法吗?