Skip to content

Commit

Permalink
libsyslog: add multicast egress options, ABI 0.1.0 -> 0.2.0
Browse files Browse the repository at this point in the history
This patch adds two new members to the syslog_data struct:

 - .log_iface: outbound interface for multicast destinations
 - .log_ttl:   IP TTL value for multicast destinations

When the .log_host member is set to an IPv4 or IPv6 multicast group the
two new members control the behavior of egressing multicast traffic.

Signed-off-by: Joachim Wiberg <[email protected]>
  • Loading branch information
troglobit committed Jan 2, 2025
1 parent 599bcb1 commit d880e03
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ pkgconfig_DATA = libsyslog.pc
pkginclude_HEADERS = syslog.h
libsyslog_la_SOURCES = syslog.c syslog.h compat.h
libsyslog_la_CPPFLAGS = $(AM_CPPFLAGS) -D_XOPEN_SOURCE=600
libsyslog_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:1
libsyslog_la_LDFLAGS = $(AM_LDFLAGS) -version-info 2:0:2
libsyslog_la_LIBADD = $(LTLIBOBJS)

# Both libsyslog and syslogd/logger require objects like lib/pidfile.o.
Expand Down
42 changes: 42 additions & 0 deletions src/syslog.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ __RCSID("$NetBSD: syslog.c,v 1.55 2015/10/26 11:44:30 roy Exp $");
#include <sys/uio.h>
#include <sys/un.h>
#include <netdb.h>
#include <net/if.h> /* if_nametoindex() */
#include <netinet/in.h> /* IN_MULTICAST, IN6_IS_ADDR_MULTICAST */

#include <errno.h>
#include <fcntl.h>
Expand Down Expand Up @@ -110,6 +112,42 @@ static socklen_t sa_len(struct sockaddr *sa)
}
#endif

/*
* Used to set outbound multicast interface and IP TTL
*/
static int set_mcopts(int sd, struct sockaddr *sa, char *iface, int ttl)
{
int idx = 0;
int rc = 0;

if (iface) {
idx = if_nametoindex(iface);
if (idx == 0)
return -1;
}

if (sa->sa_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
struct ip_mreqn imr = { .imr_ifindex = idx };

if (!IN_MULTICAST(ntohl(sin->sin_addr.s_addr)))
return 0;

rc += setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, &imr, sizeof(imr));
rc += setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
} else if (sa->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;

if (!IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
return 0;

rc += setsockopt(sd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &idx, sizeof(idx));
rc += setsockopt(sd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl));
}

return rc;
}

/*
* syslog, vsyslog --
* print message on log file; output is intended for syslogd(8).
Expand Down Expand Up @@ -534,6 +572,7 @@ vsyslogp_r(int pri, struct syslog_data *data, const char *msgid,
for (tries = 0; tries < MAXTRIES; tries++) {
if (sendto(data->log_file, tbuf, cnt, 0, sa, len) != -1)
break;

if (errno != ENOBUFS) {
disconnectlog_r(data);
connectlog_r(data);
Expand Down Expand Up @@ -634,6 +673,9 @@ connectlog_r(struct syslog_data *data)
return;
}

/* attempt to set outbound interface for multicast & ttl */
set_mcopts(data->log_file, sa, data->log_iface, data->log_ttl);

if (connect(data->log_file, sa, len) == -1) {
(void)close(data->log_file);
data->log_file = -1;
Expand Down
4 changes: 4 additions & 0 deletions src/syslog.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ struct syslog_data {
int log_mask;
void *log_host; /* struct sockaddr* */
int log_pid;
char *log_iface; /* Multicast interface */
int log_ttl; /* Multicast TTL */
};

#define SYSLOG_DATA_INIT { \
Expand All @@ -228,6 +230,8 @@ struct syslog_data {
.log_mask = 0xff, \
.log_host = NULL, \
.log_pid = -1, \
.log_iface = NULL, \
.log_ttl = 1, \
}

#ifdef __cplusplus
Expand Down

0 comments on commit d880e03

Please sign in to comment.