aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/in46_addr.c24
-rw-r--r--lib/in46_addr.h4
-rw-r--r--lib/ippool.c20
-rw-r--r--lib/tun.c13
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 */
diff --git a/lib/tun.c b/lib/tun.c
index d8e4b62..ce3eced 100644
--- a/lib/tun.c
+++ b/lib/tun.c
@@ -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);