From 2d39a12f514673dd2ea2001a33e815956e49cba1 Mon Sep 17 00:00:00 2001 From: Miroslav Lichvar Date: Tue, 2 Mar 2021 13:10:13 +0100 Subject: [PATCH] cmdmon: fix responding to IPv4 addresses on FreeBSD On FreeBSD, the source address cannot be specified when sending a message on a socket bound to a non-any IPv4 address, e.g. in default configuration 127.0.0.1. In this case, make the address unspecified. This is similar to commit 6af39d63aa93 ("ntp: don't use IP_SENDSRCADDR on bound socket"). Fixes: f06c1cfa97f8 ("cmdmon: respond from same address") --- cmdmon.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cmdmon.c b/cmdmon.c index afdfa6c..b85bae8 100644 --- a/cmdmon.c +++ b/cmdmon.c @@ -62,6 +62,9 @@ static int sock_fdu; static int sock_fd4; static int sock_fd6; +/* Flag indicating the IPv4 socket is bound to an address */ +static int bound_sock_fd4; + /* Flag indicating whether this module has been initialised or not */ static int initialised = 0; @@ -179,6 +182,9 @@ open_socket(int family) return INVALID_SOCK_FD; } + if (family == IPADDR_INET4) + bound_sock_fd4 = local_addr.ip_addr.addr.in4 != INADDR_ANY; + break; case IPADDR_UNSPEC: local_path = CNF_GetBindCommandPath(); @@ -244,6 +250,8 @@ CAM_Initialise(void) initialised = 1; + bound_sock_fd4 = 0; + sock_fdu = INVALID_SOCK_FD; sock_fd4 = open_socket(IPADDR_INET4); sock_fd6 = open_socket(IPADDR_INET6); @@ -310,6 +318,12 @@ transmit_reply(int sock_fd, int request_length, SCK_Message *message) !SCK_IsLinkLocalIPAddress(&message->remote_addr.ip.ip_addr)) message->if_index = INVALID_IF_INDEX; +#if !defined(HAVE_IN_PKTINFO) && defined(IP_SENDSRCADDR) + /* On FreeBSD a local IPv4 address cannot be specified on bound socket */ + if (message->local_addr.ip.family == IPADDR_INET4 && (sock_fd != sock_fd4 || bound_sock_fd4)) + message->local_addr.ip.family = IPADDR_UNSPEC; +#endif + if (!SCK_SendMessage(sock_fd, message, 0)) return; }