Blob Blame History Raw
autofs-5.0.9 - amd lookup move get_proximity() to parse_subs.c

From: Ian Kent <raven@themaw.net>

Later we'll need to use get_proximity() from outside modules/replicated.c
so move it to the autofs library.
---
 include/parse_subs.h |    8 ++
 lib/parse_subs.c     |  199 ++++++++++++++++++++++++++++++++++++++++++++++++++
 modules/replicated.c |  197 -------------------------------------------------
 3 files changed, 207 insertions(+), 197 deletions(-)

diff --git a/include/parse_subs.h b/include/parse_subs.h
index ecc712d..c0da5ae 100644
--- a/include/parse_subs.h
+++ b/include/parse_subs.h
@@ -18,6 +18,13 @@
 #ifndef PARSE_SUBS_H
 #define PARSE_SUBS_H
 
+#define PROXIMITY_ERROR		0x0000
+#define PROXIMITY_LOCAL         0x0001
+#define PROXIMITY_SUBNET        0x0002
+#define PROXIMITY_NET           0x0004
+#define PROXIMITY_OTHER         0x0008
+#define PROXIMITY_UNSUPPORTED   0x0010
+
 struct mapent;
 
 struct map_type_info {
@@ -26,6 +33,7 @@ struct map_type_info {
 	char *map;
 };
 
+unsigned int get_proximity(struct sockaddr *);
 const char *skipspace(const char *);
 int check_colon(const char *);
 int chunklen(const char *, int);
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
index dd2a784..b77d890 100644
--- a/lib/parse_subs.c
+++ b/lib/parse_subs.c
@@ -18,8 +18,24 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <sys/types.h>
+#include <ifaddrs.h>
+#include <net/if.h>
 #include "automount.h"
 
+#define MAX_NETWORK_LEN		255
+
+#define MAX_IFC_BUF		2048
+static int volatile ifc_buf_len = MAX_IFC_BUF;
+static int volatile ifc_last_len = 0;
+
+#define MASK_A  0x7F000000
+#define MASK_B  0xBFFF0000
+#define MASK_C  0xDFFFFF00
+
+/* Get numeric value of the n bits starting at position p */
+#define getbits(x, p, n)	((x >> (p + 1 - n)) & ~(~0 << n))
+
 struct types {
 	char *type;
 	unsigned int len;
@@ -45,6 +61,189 @@ static struct types format_type[] = {
 };
 static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types);
 
+static unsigned int ipv6_mask_cmp(uint32_t *host, uint32_t *iface, uint32_t *mask)
+{
+	unsigned int ret = 1;
+	unsigned int i;
+
+	for (i = 0; i < 4; i++) {
+		if ((host[i] & mask[i]) != (iface[i] & mask[i])) {
+			ret = 0;
+			break;
+		}
+	}
+	return ret;
+}
+
+unsigned int get_proximity(struct sockaddr *host_addr)
+{
+	struct ifaddrs *ifa = NULL;
+	struct ifaddrs *this;
+	struct sockaddr_in *addr, *msk_addr, *if_addr;
+	struct sockaddr_in6 *addr6, *msk6_addr, *if6_addr;
+	struct in_addr *hst_addr;
+	struct in6_addr *hst6_addr;
+	int addr_len;
+	char buf[MAX_ERR_BUF];
+	uint32_t mask, ha, ia, *mask6, *ha6, *ia6;
+	int ret;
+
+	addr = NULL;
+	addr6 = NULL;
+	hst_addr = NULL;
+	hst6_addr = NULL;
+	mask6 = NULL;
+	ha6 = NULL;
+	ia6 = NULL;
+	ha = 0;
+
+	switch (host_addr->sa_family) {
+	case AF_INET:
+		addr = (struct sockaddr_in *) host_addr;
+		hst_addr = (struct in_addr *) &addr->sin_addr;
+		ha = ntohl((uint32_t) hst_addr->s_addr);
+		addr_len = sizeof(*hst_addr);
+		break;
+
+	case AF_INET6:
+#ifndef WITH_LIBTIRPC
+		return PROXIMITY_UNSUPPORTED;
+#else
+		addr6 = (struct sockaddr_in6 *) host_addr;
+		hst6_addr = (struct in6_addr *) &addr6->sin6_addr;
+		ha6 = &hst6_addr->s6_addr32[0];
+		addr_len = sizeof(*hst6_addr);
+		break;
+#endif
+
+	default:
+		return PROXIMITY_ERROR;
+	}
+
+	ret = getifaddrs(&ifa);
+	if (ret) {
+		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+		logerr("getifaddrs: %s", estr);
+		return PROXIMITY_ERROR;
+	}
+
+	this = ifa;
+	while (this) {
+		if (!(this->ifa_flags & IFF_UP) ||
+		    this->ifa_flags & IFF_POINTOPOINT ||
+		    this->ifa_addr == NULL) {
+			this = this->ifa_next;
+			continue;
+		}
+
+		switch (this->ifa_addr->sa_family) {
+		case AF_INET:
+			if (host_addr->sa_family == AF_INET6)
+				break;
+			if_addr = (struct sockaddr_in *) this->ifa_addr;
+			ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len);
+			if (!ret) {
+				freeifaddrs(ifa);
+				return PROXIMITY_LOCAL;
+			}
+			break;
+
+		case AF_INET6:
+#ifdef WITH_LIBTIRPC
+			if (host_addr->sa_family == AF_INET)
+				break;
+			if6_addr = (struct sockaddr_in6 *) this->ifa_addr;
+			ret = memcmp(&if6_addr->sin6_addr, hst6_addr, addr_len);
+			if (!ret) {
+				freeifaddrs(ifa);
+				return PROXIMITY_LOCAL;
+			}
+#endif
+		default:
+			break;
+		}
+		this = this->ifa_next;
+	}
+
+	this = ifa;
+	while (this) {
+		if (!(this->ifa_flags & IFF_UP) ||
+		    this->ifa_flags & IFF_POINTOPOINT ||
+		    this->ifa_addr == NULL) {
+			this = this->ifa_next;
+			continue;
+		}
+
+		switch (this->ifa_addr->sa_family) {
+		case AF_INET:
+			if (host_addr->sa_family == AF_INET6)
+				break;
+			if_addr = (struct sockaddr_in *) this->ifa_addr;
+			ia =  ntohl((uint32_t) if_addr->sin_addr.s_addr);
+
+			/* Is the address within a localy attached subnet */
+
+			msk_addr = (struct sockaddr_in *) this->ifa_netmask;
+			mask = ntohl((uint32_t) msk_addr->sin_addr.s_addr);
+
+			if ((ia & mask) == (ha & mask)) {
+				freeifaddrs(ifa);
+				return PROXIMITY_SUBNET;
+			}
+
+			/*
+			 * Is the address within a local ipv4 network.
+			 *
+			 * Bit position 31 == 0 => class A.
+			 * Bit position 30 == 0 => class B.
+			 * Bit position 29 == 0 => class C.
+			 */
+
+			if (!getbits(ia, 31, 1))
+				mask = MASK_A;
+			else if (!getbits(ia, 30, 1))
+				mask = MASK_B;
+			else if (!getbits(ia, 29, 1))
+				mask = MASK_C;
+			else
+				break;
+
+			if ((ia & mask) == (ha & mask)) {
+				freeifaddrs(ifa);
+				return PROXIMITY_NET;
+			}
+			break;
+
+		case AF_INET6:
+#ifdef WITH_LIBTIRPC
+			if (host_addr->sa_family == AF_INET)
+				break;
+			if6_addr = (struct sockaddr_in6 *) this->ifa_addr;
+			ia6 = &if6_addr->sin6_addr.s6_addr32[0];
+
+			/* Is the address within the network of the interface */
+
+			msk6_addr = (struct sockaddr_in6 *) this->ifa_netmask;
+			mask6 = &msk6_addr->sin6_addr.s6_addr32[0];
+
+			if (ipv6_mask_cmp(ha6, ia6, mask6)) {
+				freeifaddrs(ifa);
+				return PROXIMITY_SUBNET;
+			}
+
+			/* How do we define "local network" in ipv6? */
+#endif
+		default:
+			break;
+		}
+		this = this->ifa_next;
+	}
+
+	freeifaddrs(ifa);
+
+	return PROXIMITY_OTHER;
+}
+
 /*
  * Skip whitespace in a string; if we hit a #, consider the rest of the
  * entry a comment.
diff --git a/modules/replicated.c b/modules/replicated.c
index d43f778..0c1a8a7 100644
--- a/modules/replicated.c
+++ b/modules/replicated.c
@@ -48,11 +48,8 @@
 #include <stdint.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
-#include <arpa/inet.h>
-#include <net/if.h>
 #include <netinet/in.h>
 #include <netdb.h>
-#include <ifaddrs.h>
 
 #include "rpc_subs.h"
 #include "replicated.h"
@@ -62,34 +59,9 @@
 #define MAX_ERR_BUF		512
 #endif
 
-#define MAX_IFC_BUF		2048
-static int volatile ifc_buf_len = MAX_IFC_BUF;
-static int volatile ifc_last_len = 0;
-
-#define MASK_A  0x7F000000
-#define MASK_B  0xBFFF0000
-#define MASK_C  0xDFFFFF00
-
-/* Get numeric value of the n bits starting at position p */
-#define getbits(x, p, n)	((x >> (p + 1 - n)) & ~(~0 << n))
-
 #define mymax(x, y)	(x >= y ? x : y)
 #define mmax(x, y, z)	(mymax(x, y) == x ? mymax(x, z) : mymax(y, z))
 
-unsigned int ipv6_mask_cmp(uint32_t *host, uint32_t *iface, uint32_t *mask)
-{
-	unsigned int ret = 1;
-	unsigned int i;
-
-	for (i = 0; i < 4; i++) {
-		if ((host[i] & mask[i]) != (iface[i] & mask[i])) {
-			ret = 0;
-			break;
-		}
-	}
-	return ret;
-}
-
 void seed_random(void)
 {
 	int fd;
@@ -111,175 +83,6 @@ void seed_random(void)
 	return;
 }
 
-static unsigned int get_proximity(struct sockaddr *host_addr)
-{
-	struct ifaddrs *ifa = NULL;
-	struct ifaddrs *this;
-	struct sockaddr_in *addr, *msk_addr, *if_addr;
-	struct sockaddr_in6 *addr6, *msk6_addr, *if6_addr;
-	struct in_addr *hst_addr;
-	struct in6_addr *hst6_addr;
-	int addr_len;
-	char buf[MAX_ERR_BUF];
-	uint32_t mask, ha, ia, *mask6, *ha6, *ia6;
-	int ret;
-
-	addr = NULL;
-	addr6 = NULL;
-	hst_addr = NULL;
-	hst6_addr = NULL;
-	mask6 = NULL;
-	ha6 = NULL;
-	ia6 = NULL;
-	ha = 0;
-
-	switch (host_addr->sa_family) {
-	case AF_INET:
-		addr = (struct sockaddr_in *) host_addr;
-		hst_addr = (struct in_addr *) &addr->sin_addr;
-		ha = ntohl((uint32_t) hst_addr->s_addr);
-		addr_len = sizeof(*hst_addr);
-		break;
-
-	case AF_INET6:
-#ifndef WITH_LIBTIRPC
-		return PROXIMITY_UNSUPPORTED;
-#else
-		addr6 = (struct sockaddr_in6 *) host_addr;
-		hst6_addr = (struct in6_addr *) &addr6->sin6_addr;
-		ha6 = &hst6_addr->s6_addr32[0];
-		addr_len = sizeof(*hst6_addr);
-		break;
-#endif
-
-	default:
-		return PROXIMITY_ERROR;
-	}
-
-	ret = getifaddrs(&ifa);
-	if (ret) {
-		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
-		logerr("getifaddrs: %s", estr);
-		return PROXIMITY_ERROR;
-	}
-
-	this = ifa;
-	while (this) {
-		if (!(this->ifa_flags & IFF_UP) ||
-		    this->ifa_flags & IFF_POINTOPOINT ||
-		    this->ifa_addr == NULL) {
-			this = this->ifa_next;
-			continue;
-		}
-
-		switch (this->ifa_addr->sa_family) {
-		case AF_INET:
-			if (host_addr->sa_family == AF_INET6)
-				break;
-			if_addr = (struct sockaddr_in *) this->ifa_addr;
-			ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len);
-			if (!ret) {
-				freeifaddrs(ifa);
-				return PROXIMITY_LOCAL;
-			}
-			break;
-
-		case AF_INET6:
-#ifdef WITH_LIBTIRPC
-			if (host_addr->sa_family == AF_INET)
-				break;
-			if6_addr = (struct sockaddr_in6 *) this->ifa_addr;
-			ret = memcmp(&if6_addr->sin6_addr, hst6_addr, addr_len);
-			if (!ret) {
-				freeifaddrs(ifa);
-				return PROXIMITY_LOCAL;
-			}
-#endif
-		default:
-			break;
-		}
-		this = this->ifa_next;
-	}
-
-	this = ifa;
-	while (this) {
-		if (!(this->ifa_flags & IFF_UP) ||
-		    this->ifa_flags & IFF_POINTOPOINT ||
-		    this->ifa_addr == NULL) {
-			this = this->ifa_next;
-			continue;
-		}
-
-		switch (this->ifa_addr->sa_family) {
-		case AF_INET:
-			if (host_addr->sa_family == AF_INET6)
-				break;
-			if_addr = (struct sockaddr_in *) this->ifa_addr;
-			ia =  ntohl((uint32_t) if_addr->sin_addr.s_addr);
-
-			/* Is the address within a localy attached subnet */
-
-			msk_addr = (struct sockaddr_in *) this->ifa_netmask;
-			mask = ntohl((uint32_t) msk_addr->sin_addr.s_addr);
-
-			if ((ia & mask) == (ha & mask)) {
-				freeifaddrs(ifa);
-				return PROXIMITY_SUBNET;
-			}
-
-			/*
-			 * Is the address within a local ipv4 network.
-			 *
-			 * Bit position 31 == 0 => class A.
-			 * Bit position 30 == 0 => class B.
-			 * Bit position 29 == 0 => class C.
-			 */
-
-			if (!getbits(ia, 31, 1))
-				mask = MASK_A;
-			else if (!getbits(ia, 30, 1))
-				mask = MASK_B;
-			else if (!getbits(ia, 29, 1))
-				mask = MASK_C;
-			else
-				break;
-
-			if ((ia & mask) == (ha & mask)) {
-				freeifaddrs(ifa);
-				return PROXIMITY_NET;
-			}
-			break;
-
-		case AF_INET6:
-#ifdef WITH_LIBTIRPC
-			if (host_addr->sa_family == AF_INET)
-				break;
-			if6_addr = (struct sockaddr_in6 *) this->ifa_addr;
-			ia6 = &if6_addr->sin6_addr.s6_addr32[0];
-
-			/* Is the address within the network of the interface */
-
-			msk6_addr = (struct sockaddr_in6 *) this->ifa_netmask;
-			mask6 = &msk6_addr->sin6_addr.s6_addr32[0];
-
-			if (ipv6_mask_cmp(ha6, ia6, mask6)) {
-				freeifaddrs(ifa);
-				return PROXIMITY_SUBNET;
-			}
-
-			/* How do we define "local network" in ipv6? */
-#endif
-		default:
-			break;
-		}
-		this = this->ifa_next;
-	}
-
-	freeifaddrs(ifa);
-
-	return PROXIMITY_OTHER;
-}
-
 struct host *new_host(const char *name,
 		      struct sockaddr *addr, size_t addr_len,
 		      unsigned int proximity, unsigned int weight,