From 21c70295d7ba830959117f414375406a2ef60428 Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Fri, 10 Jan 2025 20:13:17 +0000 Subject: [PATCH] mcast: Support specifying output interface for IPv6 multicast packets Specify the interface or scope_id in the IP address as a %suffix. For example:- examples/coap-client -N coap://[ff02::fd%interface] --- examples/coap-client.c | 5 +++-- man/coap-client.txt.in | 7 +++++++ src/coap_address.c | 2 +- src/coap_io.c | 6 +++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/examples/coap-client.c b/examples/coap-client.c index 46cdd2b711..03199e17b2 100644 --- a/examples/coap-client.c +++ b/examples/coap-client.c @@ -651,6 +651,7 @@ usage(const char *program, const char *version) { "\tcoap-client -m get coap+tcp://%%2Funix%%2Fdomain%%2Fpath%%2Fstream/.well-known/core\n" "\tcoap-client -m get coaps://[::1]/.well-known/core\n" "\tcoap-client -m get coaps+tcp://[::1]/.well-known/core\n" + "\tcoap-client -m get -N coap://[ff02::fd%%ens32]/.well-known/core\n" "\tcoap-client -m get coaps://%%2Funix%%2Fdomain%%2Fpath%%2Fdtls/.well-known/core\n" "\tcoap-client -m get coaps+tcp://%%2Funix%%2Fdomain%%2Fpath%%2Ftls/.well-known/core\n" "\tcoap-client -m get -T cafe coap://[::1]/time\n" @@ -1613,11 +1614,11 @@ get_session(coap_context_t *ctx, local.s = (const uint8_t *)local_addr; local.length = strlen(local_addr); - /* resolve local address where data should be sent from */ + /* resolve local address where data should be sent from (don't update port number */ info_list = coap_resolve_address_info(&local, port, port, port, port, AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV | AI_ALL, 1 << scheme, - COAP_RESOLVE_TYPE_LOCAL); + COAP_RESOLVE_TYPE_REMOTE); if (!info_list) { fprintf(stderr, "coap_resolve_address_info: %s: failed\n", local_addr); return NULL; diff --git a/man/coap-client.txt.in b/man/coap-client.txt.in index 0c4424445e..d57ffad489 100644 --- a/man/coap-client.txt.in +++ b/man/coap-client.txt.in @@ -319,6 +319,13 @@ coap-client -m get coap://[::1]/.well-known/core Query on the resource '.well-known/core' on localhost to get back a list of the known resources along with their attribute definitions. +* Example +---- +coap-client -m get -N coap://[ff02::fd%ens32]/.well-known/core +---- +Discover the available resources along with their attribute definitions using +a multicast IP sent out over the ethernet interface ens32. + * Example ---- echo -n "mode=on" | coap-client -m put \ diff --git a/src/coap_address.c b/src/coap_address.c index 857ca847df..f2864f67ae 100644 --- a/src/coap_address.c +++ b/src/coap_address.c @@ -547,7 +547,7 @@ coap_resolve_address_info(const coap_str_const_t *address, error = getaddrinfo(addrstr, NULL, &hints, &res); if (error != 0) { - coap_log_warn("getaddrinfo: %s\n", gai_strerror(error)); + coap_log_warn("getaddrinfo: %s: %s\n", addrstr, gai_strerror(error)); return NULL; } diff --git a/src/coap_io.c b/src/coap_io.c index 8b36a4c294..8fab581444 100644 --- a/src/coap_io.c +++ b/src/coap_io.c @@ -920,7 +920,11 @@ coap_socket_send(coap_socket_t *sock, coap_session_t *session, pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); - pktinfo->ipi6_ifindex = session->ifindex; + if (coap_is_mcast(&session->addr_info.remote)) { + pktinfo->ipi6_ifindex = session->addr_info.remote.addr.sin6.sin6_scope_id; + } else { + pktinfo->ipi6_ifindex = session->ifindex; + } memcpy(&pktinfo->ipi6_addr, &session->addr_info.local.addr.sin6.sin6_addr, sizeof(pktinfo->ipi6_addr));