diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/in46_addr.c | 24 | ||||
-rw-r--r-- | lib/in46_addr.h | 4 | ||||
-rw-r--r-- | lib/ippool.c | 20 | ||||
-rw-r--r-- | lib/tun.c | 13 |
4 files changed, 54 insertions, 7 deletions
diff --git a/lib/in46_addr.c b/lib/in46_addr.c index 36ad6af..79123b5 100644 --- a/lib/in46_addr.c +++ b/lib/in46_addr.c @@ -28,9 +28,11 @@ int in46a_to_af(const struct in46_addr *in) switch (in->len) { case 4: return AF_INET; +#if defined(BUILD_IPv6) case 8: case 16: return AF_INET6; +#endif default: OSMO_ASSERT(0); return -1; @@ -41,17 +43,21 @@ int in46a_to_af(const struct in46_addr *in) int in46a_to_sas(struct sockaddr_storage *out, const struct in46_addr *in) { struct sockaddr_in *sin = (struct sockaddr_in *)out; +#if defined(BUILD_IPv6) struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)out; +#endif switch (in->len) { case 4: sin->sin_family = AF_INET; sin->sin_addr = in->v4; break; +#if defined(BUILD_IPv6) case 16: sin6->sin6_family = AF_INET6; sin6->sin6_addr = in->v6; break; +#endif default: OSMO_ASSERT(0); return -1; @@ -98,7 +104,7 @@ const char *in46p_ntoa(const struct in46_prefix *in46p) * \returns 1 in case they are equal; 0 otherwise */ int in46a_equal(const struct in46_addr *a, const struct in46_addr *b) { - if (a->len == b->len && !memcmp(&a->v6, &b->v6, a->len)) + if (a->len == b->len && !memcmp(&a->v4, &b->v4, a->len)) return 1; else return 0; @@ -115,12 +121,13 @@ int in46a_prefix_equal(const struct in46_addr *a, const struct in46_addr *b) else len = a->len; - if (!memcmp(&a->v6, &b->v6, len)) + if (!memcmp(&a->v4, &b->v4, len)) return 1; else return 0; } +#if defined(BUILD_IPv6) /*! Match if IPv6 addr1 + addr2 are within same \a mask */ static int ipv6_within_mask(const struct in6_addr *addr1, const struct in6_addr *addr2, const struct in6_addr *mask) @@ -167,6 +174,7 @@ static void create_ipv6_netmask(struct in6_addr *netmask, int prefixlen) *p_netmask = htonl(0xFFFFFFFF << (32 - prefixlen)); } } +#endif /*! Determine if given \a addr is within given \a net + \a prefixlen * Builds the netmask from \a net + \a prefixlen and matches it to \a addr @@ -174,7 +182,9 @@ static void create_ipv6_netmask(struct in6_addr *netmask, int prefixlen) int in46a_within_mask(const struct in46_addr *addr, const struct in46_addr *net, size_t prefixlen) { struct in_addr netmask; +#if defined(BUILD_IPv6) struct in6_addr netmask6; +#endif if (addr->len != net->len) return 0; @@ -186,9 +196,11 @@ int in46a_within_mask(const struct in46_addr *addr, const struct in46_addr *net, return 1; else return 0; +#if defined(BUILD_IPv6) case 16: create_ipv6_netmask(&netmask6, prefixlen); return ipv6_within_mask(&addr->v6, &net->v6, &netmask6); +#endif default: OSMO_ASSERT(0); return 0; @@ -210,6 +222,7 @@ static unsigned int ipv4_netmasklen(const struct in_addr *netmask) return prefix; } +#if defined(BUILD_IPv6) static unsigned int ipv6_netmasklen(const struct in6_addr *netmask) { #if defined(__linux__) @@ -235,6 +248,7 @@ static unsigned int ipv6_netmasklen(const struct in6_addr *netmask) return prefix; } +#endif /*! Convert netmask to prefix length representation * \param[in] netmask in46_addr containing a netmask (consecutive list of 1-bit followed by consecutive list of 0-bit) @@ -245,8 +259,10 @@ unsigned int in46a_netmasklen(const struct in46_addr *netmask) switch (netmask->len) { case 4: return ipv4_netmasklen(&netmask->v4); +#if defined(BUILD_IPv6) case 16: return ipv6_netmasklen(&netmask->v6); +#endif default: OSMO_ASSERT(0); return 0; @@ -264,6 +280,7 @@ int in46a_to_eua(const struct in46_addr *src, struct ul66_t *eua) eua->v[1] = PDP_EUA_TYPE_v4; memcpy(&eua->v[2], &src->v4, 4); /* Copy a 4 byte address */ break; +#if defined(BUILD_IPv6) case 8: case 16: eua->l = 18; @@ -271,6 +288,7 @@ int in46a_to_eua(const struct in46_addr *src, struct ul66_t *eua) eua->v[1] = PDP_EUA_TYPE_v6; memcpy(&eua->v[2], &src->v6, 16); /* Copy a 16 byte address */ break; +#endif default: OSMO_ASSERT(0); return -1; @@ -296,6 +314,7 @@ int in46a_from_eua(const struct ul66_t *eua, struct in46_addr *dst) else dst->v4.s_addr = 0; break; +#if defined(BUILD_IPv6) case PDP_EUA_TYPE_v6: dst->len = 16; if (eua->l >= 18) @@ -303,6 +322,7 @@ int in46a_from_eua(const struct ul66_t *eua, struct in46_addr *dst) else memset(&dst->v6, 0, 16); break; +#endif default: return -1; } diff --git a/lib/in46_addr.h b/lib/in46_addr.h index ff26521..2b3755b 100644 --- a/lib/in46_addr.h +++ b/lib/in46_addr.h @@ -4,13 +4,17 @@ #include "../gtp/pdp.h" +#include "config.h" + /* a simple wrapper around an in6_addr to also contain the length of the address, * thereby implicitly indicating the address family of the address */ struct in46_addr { uint8_t len; union { struct in_addr v4; +#if defined(BUILD_IPv6) struct in6_addr v6; +#endif }; }; diff --git a/lib/ippool.c b/lib/ippool.c index a9a64be..ffc4388 100644 --- a/lib/ippool.c +++ b/lib/ippool.c @@ -22,6 +22,8 @@ #include "ippool.h" #include "lookup.h" +#include "config.h" + int ippool_printaddr(struct ippool_t *this) { unsigned int n; @@ -96,18 +98,24 @@ static unsigned long int ippool_hash4(struct in_addr *addr) return lookup((unsigned char *)&addr->s_addr, sizeof(addr->s_addr), 0); } +#if defined(BUILD_IPv6) static unsigned long int ippool_hash6(struct in6_addr *addr, unsigned int len) { /* TODO: Review hash spread for IPv6 */ return lookup((unsigned char *)addr->s6_addr, len, 0); } +#endif unsigned long int ippool_hash(struct in46_addr *addr) { +#if defined(BUILD_IPv6) if (addr->len == 4) return ippool_hash4(&addr->v4); else return ippool_hash6(&addr->v6, addr->len); +#else + return ippool_hash4(&addr->v4); +#endif } /* Get IP address and mask */ @@ -148,11 +156,14 @@ int ippool_aton(struct in46_addr *addr, size_t *prefixlen, const char *pool_in, *prefixlen = 32; addr->len = sizeof(struct in_addr); addr->v4 = ((struct sockaddr_in*)ai->ai_addr)->sin_addr; - } else { + } +#if defined(BUILD_IPv6) + else { *prefixlen = 128; addr->len = sizeof(struct in6_addr); addr->v6 = ((struct sockaddr_in6*)ai->ai_addr)->sin6_addr; } +#endif freeaddrinfo(ai); /* parse prefixlen */ @@ -177,7 +188,7 @@ int ippool_aton(struct in46_addr *addr, size_t *prefixlen, const char *pool_in, void in46a_inc(struct in46_addr *addr) { size_t addrlen; - uint8_t *a = (uint8_t *)&addr->v6; + uint8_t *a = (uint8_t *)&addr->v4; for (addrlen = addr->len; addrlen > 0; addrlen--) { if (++a[addrlen-1]) break; @@ -215,11 +226,12 @@ int ippool_new(struct ippool_t **this, const struct in46_prefix *dyn, const stru } else { addr = dyn->addr; addrprefixlen = dyn->prefixlen; +#if defined(BUILD_IPv6) /* we want to work with /64 prefixes, i.e. allocate /64 prefixes rather * than /128 (single IPv6 addresses) */ if (addr.len == sizeof(struct in6_addr)) addr.len = 64/8; - +#endif dynsize = (1 << (addr.len*8 - addrprefixlen)); if (flags & IPPOOL_NONETWORK) /* Exclude network address from pool */ dynsize--; @@ -404,8 +416,10 @@ int ippool_newip(struct ippool_t *this, struct ippoolm_t **member, if (addr) { if (addr->len == 4 && addr->v4.s_addr) specified = 1; +#if defined(BUILD_IPv6) if (addr->len == 16 && !IN6_IS_ADDR_UNSPECIFIED(&addr->v6)) specified = 1; +#endif } /* First check to see if this type of address is allowed */ @@ -62,7 +62,9 @@ #if defined(__linux__) +#if defined(BUILD_IPv6) #include <linux/ipv6.h> +#endif static int tun_nlattr(struct nlmsghdr *n, int nsize, int type, void *d, int dlen) { @@ -197,6 +199,7 @@ static int tun_setaddr4(struct tun_t *this, struct in_addr *addr, return 0; } +#if defined(BUILD_IPv6) static int tun_setaddr6(struct tun_t *this, struct in6_addr *addr, struct in6_addr *dstaddr, size_t prefixlen) { @@ -280,6 +283,7 @@ static int tun_setaddr6(struct tun_t *this, struct in6_addr *addr, struct in6_ad return 0; } +#endif /* BUILD_IPv6 */ int tun_setaddr(struct tun_t *this, struct in46_addr *addr, struct in46_addr *dstaddr, size_t prefixlen) { @@ -288,8 +292,10 @@ int tun_setaddr(struct tun_t *this, struct in46_addr *addr, struct in46_addr *ds case 4: netmask.s_addr = htonl(0xffffffff << (32 - prefixlen)); return tun_setaddr4(this, &addr->v4, dstaddr ? &dstaddr->v4 : NULL, &netmask); +#if defined(BUILD_IPv6) case 16: return tun_setaddr6(this, &addr->v6, dstaddr ? &dstaddr->v6 : NULL, prefixlen); +#endif default: return -1; } @@ -762,11 +768,13 @@ int tun_runscript(struct tun_t *tun, char *script) */ int netdev_ip_local_get(const char *devname, struct in46_prefix *prefix_list, size_t prefix_size, int flags) { +#if defined(BUILD_IPv6) static const uint8_t ll_prefix[] = { 0xfe,0x80, 0,0, 0,0, 0,0 }; + bool is_ipv6_ll; +#endif struct ifaddrs *ifaddr, *ifa; struct in46_addr netmask; size_t count = 0; - bool is_ipv6_ll; if (getifaddrs(&ifaddr) == -1) { return -1; @@ -792,7 +800,7 @@ int netdev_ip_local_get(const char *devname, struct in46_prefix *prefix_list, si } count++; } - +#if defined(BUILD_IPv6) if (ifa->ifa_addr->sa_family == AF_INET6 && (flags & IP_TYPE_IPv6)) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) ifa->ifa_addr; struct sockaddr_in6 *netmask6 = (struct sockaddr_in6 *) ifa->ifa_netmask; @@ -812,6 +820,7 @@ int netdev_ip_local_get(const char *devname, struct in46_prefix *prefix_list, si } count++; } +#endif } freeifaddrs(ifaddr); |