簡體   English   中英

Linux上的IPv6原始udp套接字sendto()“無效參數”錯誤

[英]sendto() “invalid argument” error with IPv6 raw udp socket on linux

我正在嘗試使用原始套接字發送udp數據包。 對於IPv4,一切正常,但是我無法克服IPv6套接字的問題,其中sendto()總是表示無效參數。 最初,我在考慮IPv6的強制校驗和,但是IPV6_CHECKSUM選項應該可以解決此問題,因此我現在不在選擇范圍內。

我將inaddr_any用於addr_from,並將一些ipv6地址用於具有相同端口的addr_to。 我查看了send_ip工具的源代碼,它手動計算校驗和並使用原始/原始套接字發送數據包,但是我希望linux根據基於策略的路由規則自動形成具有必要源地址的IP數據包。

有誰知道這個問題的根本原因是什么? 還是任何帶有raw / ipproto_udp套接字的工作示例?

提前致謝!

PS:請不要理會所有穿線的東西

發送代碼是:

typedef struct thread_data {
    char msg[BUFFER_LENGTH];
    struct sockaddr_in6 addr_to;
    struct sockaddr_in6 addr_from;
} thread_data;

void create_packet( const thread_data* data, void** packet, size_t* size ) {
    size_t msg_len = strlen(data->msg), udp_len = sizeof(struct udphdr);
    struct udphdr udp = {0};

    udp.source = data->addr_from.sin6_port;
    udp.dest   = data->addr_to.sin6_port;
    udp.len    = htons(udp_len + msg_len);
    udp.check  = 0;

    *packet = malloc( udp_len + msg_len );
    if( !(*packet) ) {
        ERROR("malloc failed" );
    }

    memcpy( *packet, &udp, sizeof(struct udphdr));
    memcpy( (*packet) + udp_len, data->msg, msg_len);

    *size = udp_len + msg_len;
}

void client_thread( void* args ) {

    thread_data* data = (thread_data*)args;

    int sock = -1;
    if ( (sock = socket( AF_INET6, SOCK_RAW, IPPROTO_UDP )) < 0 ) {
        ERROR( "failed to create socket" );
    }

    int val = 2; //I tried to play with this value, but with no luck
    if( setsockopt( sock, IPPROTO_IPV6, IPV6_CHECKSUM, &val, sizeof(val) ) < 0 ) {
        ERROR("setsockopt failed" );
    }
    ssize_t res = sendto( sock, packet, size, 0, (struct sockaddr*)&(data->addr_to), sizeof(data->addr_to));
    if ( res < 0 ) {
        ERROR( "sendto failed" );
     }
}

您實際上嘗試發送到無效的 IPv6地址。

3ffe::/16內的地址是舊的6bone地址,幾年前已退役。 這些地址現在被認為是無效的,並且可能會被現代操作系統,路由器等拒絕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM