You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
484 lines
11 KiB
484 lines
11 KiB
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,
|
|
|