Skip to content

Commit

Permalink
mcast: Support specifying output interface for IPv6 multicast packets
Browse files Browse the repository at this point in the history
Specify the interface or scope_id in the IP address as a %suffix.

For example:-

examples/coap-client -N coap://[ff02::fd%interface]
  • Loading branch information
mrdeep1 committed Jan 10, 2025
1 parent 4d84859 commit 88b86d6
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
1 change: 1 addition & 0 deletions examples/coap-client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
7 changes: 7 additions & 0 deletions man/coap-client.txt.in
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down
2 changes: 1 addition & 1 deletion src/coap_address.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
28 changes: 28 additions & 0 deletions src/coap_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ coap_socket_connect_udp(coap_socket_t *sock,

coap_address_init(&bind_addr);
bind_addr.addr.sa.sa_family = connect_addr.addr.sa.sa_family;
#if COAP_IPV6_SUPPORT
if (connect_addr.addr.sa.sa_family == AF_INET6) {
bind_addr.addr.sin6.sin6_scope_id = connect_addr.addr.sin6.sin6_scope_id;
}
#endif /* COAP_IPV6_SUPPORT */
if (bind(sock->fd, &bind_addr.addr.sa,
#if COAP_IPV4_SUPPORT
bind_addr.addr.sa.sa_family == AF_INET ?
Expand All @@ -323,6 +328,16 @@ coap_socket_connect_udp(coap_socket_t *sock,
goto error;
}
}
#if COAP_IPV6_SUPPORT
if (connect_addr.addr.sa.sa_family == AF_INET6 && !coap_is_bcast(&connect_addr)) {
int value = connect_addr.addr.sin6.sin6_scope_id;

if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, OPTVAL_T(&value),
sizeof(value)) == COAP_SOCKET_ERROR)
coap_log_warn("coap_socket_connect_udp: getsockopt IPV6_MULTICAST_IF: %d: %s\n",
value, coap_socket_strerror());
}
#endif /* COAP_IPV6_SUPPORT */
if (getsockname(sock->fd, &local_addr->addr.sa, &local_addr->size) == COAP_SOCKET_ERROR) {
coap_log_warn("coap_socket_connect_udp: getsockname for multicast socket: %s\n",
coap_socket_strerror());
Expand Down Expand Up @@ -841,6 +856,19 @@ coap_socket_send(coap_socket_t *sock, coap_session_t *session,
#else
bytes_written = send(sock->fd, data, datalen, 0);
#endif
#if COAP_IPV6_SUPPORT
} else if (session->addr_info.remote.addr.sa.sa_family == AF_INET6 &&
coap_is_mcast(&session->addr_info.remote)) {
#ifdef _WIN32
bytes_written = sendto(sock->fd, (const void *)data, (int)datalen, 0,
&session->addr_info.remote.addr.sa,
(int)session->addr_info.remote.size);
#else
bytes_written = sendto(sock->fd, (const void *)data, datalen, 0,
&session->addr_info.remote.addr.sa,
session->addr_info.remote.size);
#endif
#endif /* COAP_IPV6_SUPPORT */
} else {
#if defined(_WIN32)
DWORD dwNumberOfBytesSent = 0;
Expand Down

0 comments on commit 88b86d6

Please sign in to comment.