* it won't if it's worth its money).
*/
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
+#include <net/if.h>
#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
+#ifdef HAVE_IFADDRS_H
+#include <ifaddrs.h>
+#endif /* HAVE_IFADDRS_H */
#include "sm_inter.h"
#include "statd.h"
#include "notlist.h"
#include "log.h"
#include "ha-callout.h"
+#if SIZEOF_SOCKLEN_T - 0 == 0
+#define socklen_t int
+#endif
+
#define MAXMSGSIZE (2048 / sizeof(unsigned int))
static unsigned long xid = 0; /* RPC XID counter */
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
- sin.sin_port = port;
+ sin.sin_addr.s_addr = INADDR_ANY;
/*
* If a local hostname is given (-n option to statd), bind to the address
* specified. This is required to support clients that ignore the mon_name in
if (hp)
sin.sin_addr = *(struct in_addr *) hp->h_addr;
}
+ if (port != 0) {
+ sin.sin_port = htons(port);
+ if (bind(sockfd, &sin, sizeof(sin)) == 0)
+ goto out_success;
+ note(N_CRIT, "statd: failed to bind to outgoing port, %d\n"
+ " falling back on randomly chosen port\n", port);
+ }
if (bindresvport(sockfd, &sin) < 0) {
dprintf(N_WARNING,
"process_hosts: can't bind to reserved port\n");
}
-
+out_success:
return sockfd;
}
+#ifdef HAVE_IFADDRS_H
+/*
+ * Using the NL_ADDR(lp), reset (if needed) the hostname
+ * that will be put in the SM_NOTIFY to the hostname
+ * that is associated with the network interface
+ * that was monitored
+ */
+static void
+reset_my_name(notify_list *lp)
+{
+ struct ifaddrs *ifa = NULL, *ifap;
+ struct in_addr netaddr, tmp;
+ struct sockaddr_in *sin, *nsin;
+ struct hostent *hp;
+
+ netaddr.s_addr = inet_netof(NL_ADDR(lp));
+ if (getifaddrs(&ifa) >= 0) {
+ for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next) {
+ if (!(ifap->ifa_flags & IFF_UP))
+ continue;
+
+ note(N_DEBUG, "ifa_name %s\n", ifap->ifa_name);
+ if (ifap->ifa_addr == NULL)
+ continue;
+ if (ifap->ifa_addr->sa_family != AF_INET)
+ continue;
+
+ sin = (struct sockaddr_in *)ifap->ifa_addr;
+ nsin = (struct sockaddr_in *)ifap->ifa_netmask;
+ tmp.s_addr = sin->sin_addr.s_addr & nsin->sin_addr.s_addr;
+ if (memcmp(&tmp.s_addr, &netaddr.s_addr, sizeof(netaddr.s_addr)))
+ continue;
+ hp = gethostbyaddr((char *)&sin->sin_addr,
+ sizeof(sin->sin_addr), AF_INET);
+ if (hp == NULL)
+ continue;
+ if (strcmp(NL_MY_NAME(lp), hp->h_name)) {
+ free(NL_MY_NAME(lp));
+ NL_MY_NAME(lp)= strdup(hp->h_name);
+ note(N_DEBUG, "NL_MY_NAME %s\n", NL_MY_NAME(lp));
+ }
+ }
+ }
+ return;
+}
+#endif /* HAVE_IFADDRS_H */
/*
* Try to resolve host name for notify/callback request
*
struct rpc_msg mesg;
notify_list *lp = NULL;
XDR xdr, *xdrs = &xdr;
- int alen = sizeof(*sin);
+ socklen_t alen = sizeof(*sin);
/* Receive message */
if ((msglen = recvfrom(sockfd, msgbuf, sizeof(msgbuf), 0,
{
struct sockaddr_in sin;
struct status new_status;
+ stat_chge new_stat;
xdrproc_t func;
void *objp;
u_int32_t proc, vers, prog;
/* Use source address for notify replies */
sin.sin_addr = lp->addr;
-
+ /*
+ * Unless a static hostname has been defined
+ * set the NL_MY_NAME(lp) hostname to the
+ * one associated with the network interface
+ */
+#ifdef HAVE_IFADDRS_H
+ if (!(run_mode & STATIC_HOSTNAME))
+ reset_my_name(lp);
+#endif /* HAVE_IFADDRS_H */
func = (xdrproc_t) xdr_stat_chge;
- objp = &SM_stat_chge;
+ new_stat.state = MY_STATE;
+ new_stat.mon_name = NL_MY_NAME(lp);
+
+ objp = &new_stat;
break;
case NOTIFY_CALLBACK:
prog = NL_MY_PROG(lp);