1

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.

Tony Lin
  • 765
  • 3
  • 15
  • 35
  • 1
    `FF02:FD` is not a valid IPv6 address. – kfx Mar 06 '18 at 20:36
  • That is a multicast address - see the spec: "All CoAP Nodes" address FF0X::FD, from the "IPv6 Multicast Address Space Registry", in the "Variable Scope Multicast Addresses" space (RFC 3307). Note that there is a distinct multicast address for each scope that interested CoAP nodes should listen to; CoAP needs the Link-Local and Site-Local scopes only – Christian Gawron Apr 02 '19 at 08:04

1 Answers1

1

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));
}
kfx
  • 8,136
  • 3
  • 28
  • 52