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.
485 lines
11 KiB
485 lines
11 KiB
7 years ago
|
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,
|