Tony Lin
Tony Lin

Reputation: 805

How to join ipv6 multicast group using libcoap?

I'm new to ipv6 and libcoap. I'm using the "coap-server" example provided in libcoap for testing my coap client. I cannot get coap-server to listent to multicast to work properly. I've tried the following commands

./coap-server -g FF02::FD
# return "join: setsockopt: Protocol error"

# this method is found in https://manpages.debian.org/stretch/libcoap-1-0-bin/coap-server.5.en.html
./coap-server -g FF02:FD
# return "join: cannot resolve multicast address: Name or service not known"

Can anyone help me with this? Thanks.

Upvotes: 1

Views: 726

Answers (1)

kfx
kfx

Reputation: 8537

Looking at the Linux source code, file source/net/ipv6/ipv6_sockglue.c, this check decides whether to return the "Protocol error" error code:

    retv = -EPROTO;
    if (inet_sk(sk)->is_icsk)
        break;

So, the code returns the error if the socket is connection oriented (e.g. a TCP socket).

Looks like libcoap opens sockets for both address families (IPv4 and IPv6), for both UDP and TCP and and also secured versions of those (DTLS and TLS respectively).

As a result, you may need to change the example to iterate for all opened CoAP endpoints and find the IPv6 UDP one (I don't see any command line options for that. So, instead of using the first one as currently here:

setsockopt(ctx->endpoint->sock.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq, sizeof(mreq));

you should iterate for all open ones and check whether the proto field and the address family matches

coap_endpoint_t *ep = ctx->endpoint;
while (ep != NULL && ep->proto != COAP_PROTO_UDP
       && /* TODO: check address family */) {
    ep = ep->next;
}

if (ep != NULL) {
    result = setsockopt(ep->sock.fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq, sizeof(mreq));
}

Upvotes: 1

Related Questions