From 8086a3db780f8a4ee6943a3ef2f774fc78105327 Mon Sep 17 00:00:00 2001 From: Jon Franklin Date: Thu, 26 Mar 2020 13:22:29 -0500 Subject: llmnrd: don't exit on SO_BINDTODEVICE failure The -i option requires running llmnrd as root for SO_BINDTODEVICE to work. Packets are still filtered based on interface because only rtnl messages for addresses of the specified interface are considered in iface_nlmsg_change_addr. Instead log a warning only if SO_BINDTODEVICE fails. Signed-off-by: Jon Franklin [tk: small adjustments to commit message, check return value of iface_init] Signed-off-by: Tobias Klauser --- iface.c | 10 ++++++++-- iface.h | 2 +- llmnrd.c | 5 ++++- socket.c | 12 ++++-------- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/iface.c b/iface.c index bcbca49..ab80063 100644 --- a/iface.c +++ b/iface.c @@ -319,18 +319,24 @@ static void iface_rtnl_enumerate(int sock, uint16_t type, unsigned char family) log_err("Failed to enumerate rtnl interfaces: %s\n", strerror(errno)); } -void iface_init(int sock, const char *iface, bool ipv6, +int iface_init(int sock, const char *iface, bool ipv6, iface_event_handler_t event_handler) { INIT_LIST_HEAD(&iface_list_head); iface_event_handler = event_handler; - if (iface) + if (iface) { iface_ifindex = if_nametoindex(iface); + if (!iface_ifindex) { + log_err("Interface %s not found: %s\n", iface, strerror(errno)); + return -1; + } + } /* send RTM_GETADDR request to initially populate the interface list */ iface_rtnl_enumerate(sock, RTM_GETADDR, AF_INET); if (ipv6) iface_rtnl_enumerate(sock, RTM_GETADDR, AF_INET6); + return 0; } int iface_recv(int sock) diff --git a/iface.h b/iface.h index a8eb92c..00a39ce 100644 --- a/iface.h +++ b/iface.h @@ -30,7 +30,7 @@ enum iface_event_type { typedef void (*iface_event_handler_t)(enum iface_event_type, unsigned char af, unsigned int ifindex); -void iface_init(int sock, const char *iface, bool ipv6, +int iface_init(int sock, const char *iface, bool ipv6, iface_event_handler_t event_handler); int iface_recv(int sock); diff --git a/llmnrd.c b/llmnrd.c index d076484..ba5023c 100644 --- a/llmnrd.c +++ b/llmnrd.c @@ -236,7 +236,10 @@ int main(int argc, char **argv) goto out; llmnr_init(hostname, ipv6); - iface_init(llmnrd_sock_rtnl, iface, ipv6, &iface_event_handle); + + ret = iface_init(llmnrd_sock_rtnl, iface, ipv6, &iface_event_handle); + if (ret < 0) + goto out; nfds = max(llmnrd_sock_ipv4, llmnrd_sock_rtnl); if (llmnrd_sock_ipv6 >= 0) diff --git a/socket.c b/socket.c index 73713eb..5f58e76 100644 --- a/socket.c +++ b/socket.c @@ -36,7 +36,7 @@ static const int YES = 1; static const int TTL = 255; -static int socket_bind_to_device(int sock, const char *iface) { +static void socket_bind_to_device(int sock, const char *iface) { #ifdef SO_BINDTODEVICE /* bind socket to specific interface */ if (iface) { @@ -45,12 +45,10 @@ static int socket_bind_to_device(int sock, const char *iface) { memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, iface, sizeof(ifr.ifr_name) - 1); if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)) < 0) { - log_err("Failed to bind socket to device %s: %s\n", iface, strerror(errno)); - return -1; + log_warn("Failed to bind socket to device %s: %s\n", iface, strerror(errno)); } } #endif - return 0; } int socket_open_ipv4(uint16_t port, const char *iface) @@ -81,8 +79,7 @@ int socket_open_ipv4(uint16_t port, const char *iface) goto err; } - if (socket_bind_to_device(sock, iface) < 0) - goto err; + socket_bind_to_device(sock, iface); /* bind the socket */ memset(&sa, 0, sizeof(sa)); @@ -140,8 +137,7 @@ int socket_open_ipv6(uint16_t port, const char *iface) goto err; } - if (socket_bind_to_device(sock, iface) < 0) - goto err; + socket_bind_to_device(sock, iface); /* bind the socket */ memset(&sa, 0, sizeof(sa)); -- cgit v1.2.3-54-g00ecf