IPv6发送组播报文如何指定源IP地址?

新手上路,请多包涵

IPv6协议保留的组播地址中
ff02::1是local link multicast address
ff05::1是global link multicast address

我在写multicast socket的时候指定了目的地址为ff02::1,发出去的报文自动使用了源地址为fe80::ade2:616b:a927:5ae5

我现在需要将源地址指定成fd53:7cb8:383:f::4:10,目的地址指定为ff02::1,该如何修改socket呢?

eth0.3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::ade2:616b:a927:5ae5  prefixlen 64  scopeid 0x20<link>
        inet6 fd53:7cb8:383:f::4:10  prefixlen 64  scopeid 0x0<global>
        ether dc:a6:32:24:f4:3b  txqueuelen 1000  (Ethernet)
        RX packets 2  bytes 84 (84.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6  bytes 936 (936.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* for usleep() */
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netinet/tcp.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>

static void DieWithError(char* errorMessage)
{
    fprintf(stderr, "%s\n", errorMessage);
    exit(EXIT_FAILURE);
}

int mcast_send_socket(char* multicastIP, char* multicastPort,  int multicastTTL, struct addrinfo **multicastAddr) {

    int sock;
    struct addrinfo hints = { 0 };    /* Hints for name lookup */

    /*
      Resolve destination address for multicast datagrams
    */
    hints.ai_family   = PF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags    = AI_NUMERICHOST;
    int status;
    if ((status = getaddrinfo(multicastIP, multicastPort, &hints, multicastAddr)) != 0 )
    {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(status));
        return -1;
    }

    /*
       Create socket for sending multicast datagrams
    */
    if ( (sock = socket((*multicastAddr)->ai_family, (*multicastAddr)->ai_socktype, 0)) < 0 ) {
        perror("socket() failed");
        freeaddrinfo(*multicastAddr);
        return -1;
    }

    /*
       Set TTL of multicast packet
    */
    if ( setsockopt(sock,
                    (*multicastAddr)->ai_family == PF_INET6 ? IPPROTO_IPV6        : IPPROTO_IP,
                    (*multicastAddr)->ai_family == PF_INET6 ? IPV6_MULTICAST_HOPS : IP_MULTICAST_TTL,
                    (char*) &multicastTTL, sizeof(multicastTTL)) != 0 ) {
        perror("setsockopt() failed");
        freeaddrinfo(*multicastAddr);
        return -1;
    }

    /*
       set the sending interface
    */
    if ((*multicastAddr)->ai_family == PF_INET) {
        in_addr_t iface = INADDR_ANY; /* well, yeah, any */
        if (setsockopt (sock,
                        IPPROTO_IP,
                        IP_MULTICAST_IF,
                        (char*)&iface, sizeof(iface)) != 0) {
            perror("interface setsockopt() sending interface");
            freeaddrinfo(*multicastAddr);
            return -1;
        }

    }
    if ((*multicastAddr)->ai_family == PF_INET6) {
        const char *pcIfname = "eth0.3";
        unsigned int ifindex = if_nametoindex(pcIfname); /* 0 means 'default interface'*/
        if (setsockopt (sock,
                        IPPROTO_IPV6,
                        IPV6_MULTICAST_IF,
                        (char*)&ifindex, sizeof(ifindex)) != 0) {
            perror("interface setsockopt() sending interface");
            freeaddrinfo(*multicastAddr);
            return -1;
        }

    }


    return sock;

}

int main(int argc, char *argv[])
{
    int sock;
    struct addrinfo *multicastAddr;
    char*     multicastIP;            /* Arg: IP Multicast address */
    char*     multicastPort;          /* Arg: Server port */
    int       sendStringLen;          /* Length of string to multicast */
    int       multicastTTL;           /* Arg: TTL of multicast packets */
    int       defer_ms;               /* miliseconds to defer in between sending */

    int i;
    char sendString[8] = {0x02, 0xfd, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00};

    multicastIP   = "ff02::1";             /* First arg:   multicast IP address */
    multicastPort = "13400";             /* Second arg:  multicast port */
    sendStringLen = 8;
    defer_ms = 1000;

    multicastTTL = 1;

    sock = mcast_send_socket(multicastIP, multicastPort, multicastTTL, &multicastAddr);
    if (sock == -1 ) {
        DieWithError("mcast_send_socket() failed");
    }

    int nr = 0;
    for (;;) /* Run forever */
    {
        if ( sendto(sock, sendString, sendStringLen, 0, multicastAddr->ai_addr, multicastAddr->ai_addrlen) != sendStringLen ) {
            DieWithError("sendto() sent a different number of bytes than expected");
        }

        fprintf(stderr, "packet %d sent\n", nr);
        nr++;
        usleep(defer_ms * 1000);
    }

    return 0;
}
阅读 1.9k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题