autofs-5.0.9 - amd lookup move get_proximity() to parse_subs.c From: Ian Kent 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 #include #include +#include +#include +#include #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 #include #include -#include -#include #include #include -#include #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,