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,