osmith has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/osmo-ggsn/+/36070?usp=email )


Change subject: Move in46_addr to libosmocore
......................................................................

Move in46_addr to libosmocore

I'm in the process of extending the public API of OsmoGGSN's libgtp, so
a GSN can be created with either IPv4 or IPv6. The in46_addr code from
osmo-ggsn.git provides a good abstraction for that. I've considered
making it public in libgtp, but given that it is generic code that could
be used outside of libgtp in other Osmocom projects, put it in
libosmocore instead.

Depends: libosmocore I31078f130ec42aeaa5ead1dde82fdd1eb44d992b
Change-Id: I8f4d9d78689909a149683583cfe36bcdc3f7cbc7
---
M TODO-RELEASE
M ggsn/ggsn.c
M ggsn/ggsn.h
M lib/Makefile.am
D lib/in46_addr.c
D lib/in46_addr.h
M lib/ippool.h
M lib/netdev.h
M lib/tun.h
M lib/util.c
M tests/lib/Makefile.am
D tests/lib/in46a_test.c
D tests/lib/in46a_test.ok
D tests/lib/in46a_v6_test.ok
M tests/lib/ippool_test.c
M tests/testsuite.at
16 files changed, 27 insertions(+), 938 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ggsn refs/changes/70/36070/1

diff --git a/TODO-RELEASE b/TODO-RELEASE
index 22cfd1d..38ddde9 100644
--- a/TODO-RELEASE
+++ b/TODO-RELEASE
@@ -9,3 +9,4 @@
 #library       what            description / commit summary line
 libgtp         REMOVE          remove GTP cause defines of reserved values
 libgtpnl > 1.2.5               gtp_tunnel_set_family()
+libosmocore > 1.9.0            moved in46_addr code to libosmocore
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index d64e82f..de3f614 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -43,6 +43,7 @@
 #include <netinet/ip6.h>

 #include <osmocom/core/timer.h>
+#include <osmocom/core/in46_addr.h>
 #include <osmocom/ctrl/control_if.h>
 #include <osmocom/gsm/apn.h>

@@ -52,7 +53,6 @@
 #include "../lib/tun.h"
 #include "../lib/ippool.h"
 #include "../lib/syserr.h"
-#include "../lib/in46_addr.h"
 #include "../lib/gtp-kernel.h"
 #include "../lib/util.h"
 #include "../lib/icmpv6.h"
diff --git a/ggsn/ggsn.h b/ggsn/ggsn.h
index 7a3204f..5b8cc9b 100644
--- a/ggsn/ggsn.h
+++ b/ggsn/ggsn.h
@@ -7,13 +7,13 @@
 #include <osmocom/core/select.h>
 #include <osmocom/core/timer.h>
 #include <osmocom/core/tdef.h>
+#include <osmocom/core/in46_addr.h>
 #include <osmocom/ctrl/control_if.h>
 #include <osmocom/gtp/gtp.h>

 #include "../lib/tun.h"
 #include "../lib/ippool.h"
 #include "../lib/syserr.h"
-#include "../lib/in46_addr.h"

 #include "sgsn.h"

diff --git a/lib/Makefile.am b/lib/Makefile.am
index 1fdc93f..c24b63f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -5,7 +5,6 @@
                 gnugetopt.h \
                 gtp-kernel.h \
                 icmpv6.h \
-                in46_addr.h \
                 ippool.h \
                 lookup.h \
                 netdev.h \
@@ -29,7 +28,6 @@
                    getopt.c \
                    getopt1.c \
                    icmpv6.c \
-                   in46_addr.c \
                    ippool.c \
                    lookup.c \
                    netdev.c \
diff --git a/lib/in46_addr.c b/lib/in46_addr.c
deleted file mode 100644
index f5cdf41..0000000
--- a/lib/in46_addr.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * IPv4/v6 address functions.
- * Copyright (C) 2017 by Harald Welte <lafo...@gnumonks.org>
- *
- * The contents of this file may be used under the terms of the GNU
- * General Public License Version 2, provided that the above copyright
- * notice and this permission notice is included in all copies or
- * substantial portions of the software.
- *
- */
-
-#include "../lib/in46_addr.h"
-#include <osmocom/gtp/pdp.h>
-
-#include <osmocom/core/utils.h>
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <stdlib.h>
-#include <string.h>
-
-/*! Return the address family of given \reff in46_addr argument */
-int in46a_to_af(const struct in46_addr *in)
-{
-       switch (in->len) {
-       case 4:
-               return AF_INET;
-       case 8:
-       case 16:
-               return AF_INET6;
-       default:
-               OSMO_ASSERT(0);
-               return -1;
-       }
-}
-
-/*! Convert \ref in46_addr to sockaddr_storage */
-int in46a_to_sas(struct sockaddr_storage *out, const struct in46_addr *in)
-{
-       struct sockaddr_in *sin = (struct sockaddr_in *)out;
-       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)out;
-
-       switch (in->len) {
-       case 4:
-               sin->sin_family = AF_INET;
-               sin->sin_addr = in->v4;
-               break;
-       case 16:
-               sin6->sin6_family = AF_INET6;
-               sin6->sin6_addr = in->v6;
-               break;
-       default:
-               OSMO_ASSERT(0);
-               return -1;
-       }
-
-       return 0;
-}
-
-/*! Convenience wrapper around inet_ntop() for in46_addr.
- *  \param[in] in the in46_addr to print
- *  \param[out] dst destination buffer where string representation of the 
address is stored
- *  \param[out] dst_size size dst. Usually it should be at least 
INET6_ADDRSTRLEN.
- *  \return address of dst on success, NULL on error */
-const char *in46a_ntop(const struct in46_addr *in, char *dst, socklen_t 
dst_size)
-{
-       int af;
-
-       if (!in || in->len == 0) {
-               strncpy(dst, "UNDEFINED", dst_size);
-               return dst;
-       }
-
-       af = in46a_to_af(in);
-       if (af < 0)
-               return NULL;
-
-       return inet_ntop(af, (const void *) &in->v4, dst, dst_size);
-}
-
-/* like inet_ntoa() */
-const char *in46a_ntoa(const struct in46_addr *in46)
-{
-       static char addrstr_buf[256];
-       if (in46a_ntop(in46, addrstr_buf, sizeof(addrstr_buf)) < 0)
-               return "INVALID";
-       else
-               return addrstr_buf;
-}
-
-const char *in46p_ntoa(const struct in46_prefix *in46p)
-{
-       static char addrstr_buf[256];
-       snprintf(addrstr_buf, sizeof(addrstr_buf), "%s/%u", 
in46a_ntoa(&in46p->addr), in46p->prefixlen);
-       return addrstr_buf;
-}
-
-/*! Determine if two in46_addr are equal or not
- *  \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))
-               return 1;
-       else
-               return 0;
-}
-
-/*! Determine if two in46_addr prefix are equal or not
- *  The prefix length is determined by the shortest of the prefixes of a and b
- *  \returns 1 in case the common prefix are equal; 0 otherwise */
-int in46a_prefix_equal(const struct in46_addr *a, const struct in46_addr *b)
-{
-       unsigned int len;
-       if (a->len > b->len)
-               len = b->len;
-       else
-               len = a->len;
-
-       if (!memcmp(&a->v6, &b->v6, len))
-               return 1;
-       else
-               return 0;
-}
-
-/*! 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)
-{
-       struct in6_addr masked = *addr2;
-#if defined(__linux__)
-       masked.s6_addr32[0] &= mask->s6_addr32[0];
-       masked.s6_addr32[1] &= mask->s6_addr32[1];
-       masked.s6_addr32[2] &= mask->s6_addr32[2];
-       masked.s6_addr32[3] &= mask->s6_addr32[3];
-#else
-       masked.__u6_addr.__u6_addr32[0] &= mask->__u6_addr.__u6_addr32[0];
-       masked.__u6_addr.__u6_addr32[1] &= mask->__u6_addr.__u6_addr32[1];
-       masked.__u6_addr.__u6_addr32[2] &= mask->__u6_addr.__u6_addr32[2];
-       masked.__u6_addr.__u6_addr32[3] &= mask->__u6_addr.__u6_addr32[3];
-#endif
-       if (!memcmp(addr1, &masked, sizeof(struct in6_addr)))
-               return 1;
-       else
-               return 0;
-}
-
-/*! Create an IPv6 netmask from the given prefix length */
-static void create_ipv6_netmask(struct in6_addr *netmask, int prefixlen)
-{
-       uint32_t *p_netmask;
-       memset(netmask, 0, sizeof(struct in6_addr));
-       if (prefixlen < 0)
-               prefixlen = 0;
-       else if (128 < prefixlen)
-               prefixlen = 128;
-
-#if defined(__linux__)
-       p_netmask = &netmask->s6_addr32[0];
-#else
-       p_netmask = &netmask->__u6_addr.__u6_addr32[0];
-#endif
-       while (32 < prefixlen) {
-               *p_netmask = 0xffffffff;
-               p_netmask++;
-               prefixlen -= 32;
-       }
-       if (prefixlen != 0) {
-               *p_netmask = htonl(0xFFFFFFFF << (32 - prefixlen));
-       }
-}
-
-/*! 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
- *  \returns 1 in case of a match, 0 otherwise */
-int in46a_within_mask(const struct in46_addr *addr, const struct in46_addr 
*net, size_t prefixlen)
-{
-       struct in_addr netmask;
-       struct in6_addr netmask6;
-
-       if (addr->len != net->len)
-               return 0;
-
-       switch (addr->len) {
-       case 4:
-               netmask.s_addr = htonl(0xFFFFFFFF << (32 - prefixlen));
-               if ((addr->v4.s_addr & netmask.s_addr) == net->v4.s_addr)
-                       return 1;
-               else
-                       return 0;
-       case 16:
-               create_ipv6_netmask(&netmask6, prefixlen);
-               return ipv6_within_mask(&addr->v6, &net->v6, &netmask6);
-       default:
-               OSMO_ASSERT(0);
-               return 0;
-       }
-}
-
-static unsigned int ipv4_netmasklen(const struct in_addr *netmask)
-{
-       uint32_t bits = netmask->s_addr;
-       uint8_t *b = (uint8_t*) &bits;
-       unsigned int i, prefix = 0;
-
-       for (i = 0; i < 4; i++) {
-               while (b[i] & 0x80) {
-                       prefix++;
-                       b[i] = b[i] << 1;
-               }
-       }
-       return prefix;
-}
-
-static unsigned int ipv6_netmasklen(const struct in6_addr *netmask)
-{
-       #if defined(__linux__)
-               #define ADDRFIELD(i) s6_addr32[i]
-       #else
-               #define ADDRFIELD(i) __u6_addr.__u6_addr32[i]
-       #endif
-
-       unsigned int i, j, prefix = 0;
-
-       for (j = 0; j < 4; j++) {
-               uint32_t bits = netmask->ADDRFIELD(j);
-               uint8_t *b = (uint8_t*) &bits;
-               for (i = 0; i < 4; i++) {
-                       while (b[i] & 0x80) {
-                               prefix++;
-                               b[i] = b[i] << 1;
-                       }
-               }
-       }
-
-       #undef ADDRFIELD
-
-       return prefix;
-}
-
-/*! 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)
- *  \returns prefix length representation of the netmask (count of 1-bit from 
the start of the netmask)
- */
-unsigned int in46a_netmasklen(const struct in46_addr *netmask)
-{
-       switch (netmask->len) {
-       case 4:
-               return ipv4_netmasklen(&netmask->v4);
-       case 16:
-               return ipv6_netmasklen(&netmask->v6);
-       default:
-               OSMO_ASSERT(0);
-               return 0;
-       }
-}
-
-/*! Convert given array of in46_addr to PDP End User Address
- *  \param[in] src Array containing 1 or 2 in46_addr
- *  \param[out] eua End User Address structure to fill
- *  \returns 0 on success; negative on error
- *
- * In case size is 2, this function expects to find exactly one IPv4 and one
- * IPv6 addresses in src. */
-int in46a_to_eua(const struct in46_addr *src, unsigned int size, struct ul66_t 
*eua)
-{
-       const struct in46_addr *src_v4, *src_v6;
-       if (size == 1) {
-               switch (src->len) {
-               case 4:
-                       eua->l = 6;
-                       eua->v[0] = PDP_EUA_ORG_IETF;
-                       eua->v[1] = PDP_EUA_TYPE_v4;
-                       memcpy(&eua->v[2], &src->v4, 4);        /* Copy a 4 
byte address */
-                       break;
-               case 8:
-               case 16:
-                       eua->l = 18;
-                       eua->v[0] = PDP_EUA_ORG_IETF;
-                       eua->v[1] = PDP_EUA_TYPE_v6;
-                       memcpy(&eua->v[2], &src->v6, 16);       /* Copy a 16 
byte address */
-                       break;
-               default:
-                       OSMO_ASSERT(0);
-                       return -1;
-               }
-               return 0;
-       }
-
-       if (src[0].len == src[1].len)
-               return -1; /* we should have a v4 and a v6 address */
-
-       src_v4 = (src[0].len == 4) ? &src[0] : &src[1];
-       src_v6 = (src[0].len == 4) ? &src[1] : &src[0];
-
-       eua->l = 22;
-       eua->v[0] = PDP_EUA_ORG_IETF;
-       eua->v[1] = PDP_EUA_TYPE_v4v6;
-       memcpy(&eua->v[2], &src_v4->v4, 4);
-       memcpy(&eua->v[6], &src_v6->v6, 16);
-
-       return 0;
-}
-
-/*! Convert given PDP End User Address to an array of in46_addr
- *  \param[in] eua End User Address structure to parse
- *  \param[out] dst Array containing 2 in46_addr
- *  \returns number of parsed addresses (1 or 2) on success; negative on error
- *
- * This function expects to receive an End User Address struct together with an
- * array of 2 zeroed in46_addr structs. The in46_addr structs are filled in
- * order, hence if the function returns 1 the parsed address will be stored in
- * the first struct and the second one will be left intact. If 2 is returned, 
it
- * is guaranteed that one of them is an IPv4 and the other one is an IPv6, but
- * the order in which they are presented is not specified and must be
- * discovered for instance by checking the len field of each address.
- */
-int in46a_from_eua(const struct ul66_t *eua, struct in46_addr *dst)
-{
-       if (eua->l < 2)
-               goto default_to_dyn_v4;
-
-       if (eua->v[0] != 0xf1)
-               return -1;
-
-       switch (eua->v[1]) {
-       case PDP_EUA_TYPE_v4:
-               dst->len = 4;
-               if (eua->l >= 6)
-                       memcpy(&dst->v4, &eua->v[2], 4);        /* Copy a 4 
byte address */
-               else
-                       dst->v4.s_addr = 0;
-               return 1;
-       case PDP_EUA_TYPE_v6:
-               dst->len = 16;
-               if (eua->l >= 18)
-                       memcpy(&dst->v6, &eua->v[2], 16);       /* Copy a 16 
byte address */
-               else
-                       memset(&dst->v6, 0, 16);
-               return 1;
-       case PDP_EUA_TYPE_v4v6:
-               /* 3GPP TS 29.060, section 7.7.27 */
-               switch (eua->l) {
-                       case 2: /* v4 & v6 dynamic */
-                               dst[0].v4.s_addr = 0;
-                               memset(&dst[1].v6, 0, 16);
-                               break;
-                       case 6: /* v4 static, v6 dynamic */
-                               memcpy(&dst[0].v4, &eua->v[2], 4);
-                               memset(&dst[1].v6, 0, 16);
-                               break;
-                       case 18: /* v4 dynamic, v6 static */
-                               dst[0].v4.s_addr = 0;
-                               memcpy(&dst[1].v6, &eua->v[2], 16);
-                               break;
-                       case 22:  /* v4 & v6 static */
-                               memcpy(&dst[0].v4, &eua->v[2], 4);
-                               memcpy(&dst[1].v6, &eua->v[6], 16);
-                               break;
-                       default:
-                               return -1;
-               }
-               dst[0].len = 4;
-               dst[1].len = 16;
-               return 2;
-       default:
-               return -1;
-       }
-
-default_to_dyn_v4:
-       /* assume dynamic IPv4 by default */
-       dst->len = 4;
-       dst->v4.s_addr = 0;
-       return 1;
-}
diff --git a/lib/in46_addr.h b/lib/in46_addr.h
deleted file mode 100644
index c3c9e9c..0000000
--- a/lib/in46_addr.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#pragma once
-#include <stdint.h>
-#include <netinet/in.h>
-
-#include <osmocom/gtp/pdp.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;
-               struct in6_addr v6;
-       };
-};
-
-struct in46_prefix {
-       struct in46_addr addr;
-       uint8_t prefixlen;
-};
-
-extern int in46a_to_af(const struct in46_addr *in);
-extern int in46a_to_sas(struct sockaddr_storage *out, const struct in46_addr 
*in);
-extern const char *in46a_ntop(const struct in46_addr *in, char *dst, socklen_t 
dst_size);
-extern const char *in46a_ntoa(const struct in46_addr *in46);
-extern const char *in46p_ntoa(const struct in46_prefix *in46p);
-extern int in46a_equal(const struct in46_addr *a, const struct in46_addr *b);
-extern int in46a_prefix_equal(const struct in46_addr *a, const struct 
in46_addr *b);
-extern int in46a_within_mask(const struct in46_addr *addr, const struct 
in46_addr *net, size_t prefixlen);
-unsigned int in46a_netmasklen(const struct in46_addr *netmask);
-
-int in46a_to_eua(const struct in46_addr *src, unsigned int size, struct ul66_t 
*eua);
-int in46a_from_eua(const struct ul66_t *eua, struct in46_addr *dst);
-
-static inline bool in46a_is_v6(const struct in46_addr *addr) {
-       return addr->len == 8 || addr->len == 16;
-}
-
-static inline bool in46a_is_v4(const struct in46_addr *addr) {
-       return addr->len == sizeof(struct in_addr);
-}
diff --git a/lib/ippool.h b/lib/ippool.h
index 406938e..8baf330 100644
--- a/lib/ippool.h
+++ b/lib/ippool.h
@@ -12,7 +12,7 @@
 #ifndef _IPPOOL_H
 #define _IPPOOL_H

-#include "../lib/in46_addr.h"
+#include <osmocom/core/in46_addr.h>
 #include <osmocom/gtp/gtp.h>

 /* Assuming that the address space is fragmented we need a hash table
diff --git a/lib/netdev.h b/lib/netdev.h
index 1bce814..196340e 100644
--- a/lib/netdev.h
+++ b/lib/netdev.h
@@ -13,7 +13,7 @@

 #include <net/if.h>

-#include "../lib/in46_addr.h"
+#include <osmocom/core/in46_addr.h>

 #define TUN_NLBUFSIZE   1024

diff --git a/lib/tun.h b/lib/tun.h
index 36a4f7e..394d816 100644
--- a/lib/tun.h
+++ b/lib/tun.h
@@ -16,7 +16,7 @@
 #include <stdbool.h>
 #include <net/if.h>

-#include "../lib/in46_addr.h"
+#include <osmocom/core/in46_addr.h>

 #define PACKET_MAX      8196   /* Maximum packet size we receive */
 #define TUN_SCRIPTSIZE   256
diff --git a/lib/util.c b/lib/util.c
index f29884a..30401d5 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -9,10 +9,10 @@
  *
  */

+#include <osmocom/core/in46_addr.h>
 #include <osmocom/gtp/pdp.h>

 #include "ippool.h"
-#include "in46_addr.h"

 /*! Get the peer of pdp based on IP version used.
 *  \param[in] pdp PDP context to select the peer from.
diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am
index 7c01915..9f672f8 100644
--- a/tests/lib/Makefile.am
+++ b/tests/lib/Makefile.am
@@ -9,10 +9,9 @@
             ippool_test.err \
             ippool_v6_test.ok \
             ippool_v6_test.err \
-            in46a_test.ok \
-            in46a_v6_test.ok
+            $(NULL)

-check_PROGRAMS = ippool_test in46a_test
+check_PROGRAMS = ippool_test

 ippool_test_SOURCES = \
        ippool_test.c \
@@ -22,12 +21,3 @@
        $(top_builddir)/lib/libmisc.a \
        $(LIBOSMOCORE_LIBS) \
        $(NULL)
-
-in46a_test_SOURCES = \
-       in46a_test.c \
-       $(NULL)
-
-in46a_test_LDADD = \
-       $(top_builddir)/lib/libmisc.a \
-       $(LIBOSMOCORE_LIBS) \
-       $(NULL)
diff --git a/tests/lib/in46a_test.c b/tests/lib/in46a_test.c
deleted file mode 100644
index d576124..0000000
--- a/tests/lib/in46a_test.c
+++ /dev/null
@@ -1,460 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-#include <osmocom/core/utils.h>
-#include <osmocom/core/application.h>
-#include <osmocom/core/logging.h>
-#include <osmocom/core/msgb.h>
-#include <osmocom/core/bits.h>
-
-#include "../../lib/in46_addr.h"
-#include "../../lib/syserr.h"
-
-static const struct in46_addr g_ia4 = {
-       .len = 4,
-       .v4.s_addr = 0x0d0c0b0a,
-};
-
-static void test_in46a_to_af(void)
-{
-       printf("Testing in46a_to_af() with IPv4 addresses\n");
-
-       OSMO_ASSERT(in46a_to_af(&g_ia4) == AF_INET);
-}
-
-static void test_in46a_to_sas(void)
-{
-       struct sockaddr_storage ss;
-       struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
-
-       printf("Testing in46a_to_sas() with IPv4 addresses\n");
-
-       memset(&ss, 0, sizeof(ss));
-       OSMO_ASSERT(in46a_to_sas(&ss, &g_ia4) == 0);
-       OSMO_ASSERT(sin->sin_family == AF_INET);
-       OSMO_ASSERT(sin->sin_addr.s_addr == g_ia4.v4.s_addr);
-}
-
-static void test_in46a_ntop(void)
-{
-       struct in46_addr ia;
-       char buf[256];
-       const char *res;
-
-       printf("Testing in46a_ntop() with IPv4 addresses\n");
-
-       res = in46a_ntop(NULL, buf, sizeof(buf));
-       OSMO_ASSERT(res && !strcmp(res, "UNDEFINED"));
-       printf("res = %s\n", res);
-
-       ia.len = 0;
-       res = in46a_ntop(&ia, buf, sizeof(buf));
-       printf("res = %s\n", res);
-       OSMO_ASSERT(res && !strcmp(res, "UNDEFINED"));
-
-       ia.len = 4;
-       ia.v4.s_addr = htonl(0x01020304);
-       res = in46a_ntop(&ia, buf, sizeof(buf));
-       OSMO_ASSERT(res && !strcmp(res, "1.2.3.4"));
-       printf("res = %s\n", res);
-}
-
-static void test_in46p_ntoa(void)
-{
-       const struct in46_prefix ip46 = {
-               .prefixlen = 24,
-               .addr = {
-                       .len = 4,
-                       .v4.s_addr = htonl(0x10203000),
-               },
-       };
-       printf("in46p_ntoa() returns %s\n", in46p_ntoa(&ip46));
-}
-
-static void test_in46a_equal(void)
-{
-       struct in46_addr b;
-
-       printf("Testing in46a_equal() with IPv4 addresses\n");
-
-       memset(&b, 0xff, sizeof(b));
-       b.len = g_ia4.len;
-       b.v4.s_addr = g_ia4.v4.s_addr;
-       OSMO_ASSERT(in46a_equal(&g_ia4, &b));
-}
-
-static int log_in46a_within_mask(const struct in46_addr *addr, const struct 
in46_addr *net,
-                                size_t prefixlen)
-{
-       int rc;
-
-       printf("in46a_within_mask(%s, ", in46a_ntoa(addr));
-       printf("%s, %lu) = ", in46a_ntoa(net), prefixlen);
-
-       rc = in46a_within_mask(addr, net, prefixlen);
-       printf("%d\n", rc);
-
-       return rc;
-}
-
-static void test_in46a_within_mask(void)
-{
-       struct in46_addr addr, mask;
-
-       printf("Testing in46a_within_mask() with IPv4 addresses\n");
-
-       addr = g_ia4;
-       mask = g_ia4;
-       OSMO_ASSERT(log_in46a_within_mask(&addr, &mask, 32));
-
-       mask.v4.s_addr = htonl( ntohl(mask.v4.s_addr) & 0xfffffffC );
-       OSMO_ASSERT(log_in46a_within_mask(&addr, &mask, 30));
-
-       mask.v4.s_addr = htonl( ntohl(mask.v4.s_addr) & 0xfff80000 );
-       OSMO_ASSERT(log_in46a_within_mask(&addr, &mask, 13));
-
-       addr.v4.s_addr = htonl(ntohl(addr.v4.s_addr) + 1);
-       mask = g_ia4;
-       OSMO_ASSERT(!log_in46a_within_mask(&addr, &mask, 32));
-       mask.v4.s_addr = htonl( ntohl(mask.v4.s_addr) & 0xfffffffC );
-       OSMO_ASSERT(log_in46a_within_mask(&addr, &mask, 30));
-}
-
-static void test_in46a_to_eua(void)
-{
-       struct ul66_t eua;
-
-       printf("testing in46a_to_eua() with IPv4 addresses\n");
-
-#if 0  /* triggers assert in current implementation */
-       const struct in46_addr ia_invalid = { .len = 3, };
-       OSMO_ASSERT(in46a_to_eua(&ia_invalid, &eua) < 0);
-#endif
-
-       /* IPv4 address */
-       OSMO_ASSERT(in46a_to_eua(&g_ia4, 1, &eua) == 0);
-       OSMO_ASSERT(eua.v[0] == PDP_EUA_ORG_IETF);
-       OSMO_ASSERT(eua.v[1] == PDP_EUA_TYPE_v4);
-       OSMO_ASSERT(osmo_load32le(&eua.v[2]) == g_ia4.v4.s_addr);
-}
-
-static void test_in46a_from_eua(void)
-{
-       struct in46_addr ia[2];
-       struct ul66_t eua;
-       const uint8_t v4_unspec[] = { PDP_EUA_ORG_IETF, PDP_EUA_TYPE_v4 };
-       const uint8_t v4_spec[] = { PDP_EUA_ORG_IETF, PDP_EUA_TYPE_v4, 1,2,3,4 
};
-       memset(&eua, 0, sizeof(eua));
-
-       printf("Testing in46a_from_eua() with IPv4 addresses\n");
-
-       /* default: v4 unspec */
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) == 1);
-       OSMO_ASSERT(ia[0].len == 4);
-       OSMO_ASSERT(ia[0].v4.s_addr == 0);
-
-       /* invalid */
-       eua.v[0] = 0x23;
-       eua.v[1] = PDP_EUA_TYPE_v4;
-       eua.l = 6;
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) < 0);
-
-       /* invalid */
-       eua.v[0] = PDP_EUA_ORG_IETF;
-       eua.v[1] = 0x23;
-       eua.l = 6;
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) < 0);
-
-       /* unspecified V4 */
-       memcpy(eua.v, v4_unspec, sizeof(v4_unspec));
-       eua.l = sizeof(v4_unspec);
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) == 1);
-       OSMO_ASSERT(ia[0].len == 4);
-       OSMO_ASSERT(ia[0].v4.s_addr == 0);
-
-       /* specified V4 */
-       memcpy(eua.v, v4_spec, sizeof(v4_spec));
-       eua.l = sizeof(v4_spec);
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) == 1);
-       OSMO_ASSERT(ia[0].len == 4);
-       OSMO_ASSERT(ia[0].v4.s_addr == htonl(0x01020304));
-}
-
-static void test_in46a_netmasklen(void)
-{
-       struct in46_addr netmask;
-       unsigned int len;
-
-       printf("Testing in46a_netmasklen() with IPv4 addresses\n");
-       netmask.len = 4;
-
-       netmask.v4.s_addr = 0xffffffff;
-       len = in46a_netmasklen(&netmask);
-       OSMO_ASSERT(len == 32);
-
-       netmask.v4.s_addr = 0x00ffffff;
-       len = in46a_netmasklen(&netmask);
-       OSMO_ASSERT(len == 24);
-
-       netmask.v4.s_addr = 0x00f0ffff;
-       len = in46a_netmasklen(&netmask);
-       OSMO_ASSERT(len == 20);
-
-       netmask.v4.s_addr = 0x000000fe;
-       len = in46a_netmasklen(&netmask);
-       OSMO_ASSERT(len == 7);
-
-       netmask.v4.s_addr = 0x00000000;
-       len = in46a_netmasklen(&netmask);
-       OSMO_ASSERT(len == 0);
-}
-
-/* IPv6 specific tests */
-
-static const struct in46_addr g_ia6 = {
-       .len = 16,
-       .v6.s6_addr = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
-};
-
-static void test_in46a_to_af_v6(void)
-{
-       struct in46_addr ia;
-
-       printf("Testing in46a_to_af() with IPv6 addresses\n");
-
-       OSMO_ASSERT(in46a_to_af(&g_ia6) == AF_INET6);
-
-       ia.len = 8;
-       OSMO_ASSERT(in46a_to_af(&ia) == AF_INET6);
-}
-
-static void test_in46a_to_sas_v6(void)
-{
-       struct sockaddr_storage ss;
-       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) &ss;
-
-       printf("Testing in46a_to_sas() with IPv6 addresses\n");
-
-       memset(&ss, 0, sizeof(ss));
-       OSMO_ASSERT(in46a_to_sas(&ss, &g_ia6) == 0);
-       OSMO_ASSERT(sin6->sin6_family == AF_INET6);
-       OSMO_ASSERT(!memcmp(&sin6->sin6_addr, &g_ia6.v6, 
sizeof(sin6->sin6_addr)));
-}
-
-static void test_in46a_ntop_v6(void)
-{
-       char buf[256];
-       const char *res;
-
-       printf("Testing in46a_ntop() with IPv6 addresses\n");
-
-       res = in46a_ntop(&g_ia6, buf, sizeof(buf));
-       OSMO_ASSERT(res && !strcmp(res, "102:304:506:708:90a:b0c:d0e:f10"));
-       printf("res = %s\n", res);
-}
-
-static void test_in46a_equal_v6(void)
-{
-       struct in46_addr b;
-
-       printf("Testing in46a_equal() with IPv6 addresses\n");
-
-       memset(&b, 0xff, sizeof(b));
-       b.len = g_ia6.len;
-       b.v6 = g_ia6.v6;
-       OSMO_ASSERT(in46a_equal(&g_ia6, &b));
-}
-
-static void test_in46a_to_eua_v6(void)
-{
-       const struct in46_addr ia_v6_8 = {
-               .len = 8,
-               .v6.s6_addr = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
-       };
-       struct ul66_t eua;
-
-       printf("Testing in46a_to_eua() with IPv6 addresses\n");
-
-       /* IPv6 address */
-       OSMO_ASSERT(in46a_to_eua(&g_ia6, 1, &eua) == 0);
-       OSMO_ASSERT(eua.v[0] == PDP_EUA_ORG_IETF);
-       OSMO_ASSERT(eua.v[1] == PDP_EUA_TYPE_v6);
-       OSMO_ASSERT(!memcmp(&eua.v[2], &g_ia6.v6, 16));
-
-       /* IPv6 address with prefix / length 8 */
-       OSMO_ASSERT(in46a_to_eua(&ia_v6_8, 1, &eua) == 0);
-       OSMO_ASSERT(eua.v[0] == PDP_EUA_ORG_IETF);
-       OSMO_ASSERT(eua.v[1] == PDP_EUA_TYPE_v6);
-       OSMO_ASSERT(!memcmp(&eua.v[2], &ia_v6_8.v6, 16));
-}
-
-static void test_in46a_to_eua_v4v6() {
-       const struct in46_addr ia_v4v6[2] = {
-               {
-               .len = 16,
-               .v6.s6_addr = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 },
-               },
-               {
-               .len = 4,
-               .v4.s_addr = 0x0d0c0b0a,
-               }
-       };
-       struct ul66_t eua;
-       printf("Testing in46a_to_eua() with IPv4v6 addresses\n");
-
-       /* IPv4 address */
-       OSMO_ASSERT(in46a_to_eua(ia_v4v6, 2, &eua) == 0);
-       OSMO_ASSERT(eua.v[0] == PDP_EUA_ORG_IETF);
-       OSMO_ASSERT(eua.v[1] == PDP_EUA_TYPE_v4v6);
-       OSMO_ASSERT(osmo_load32le(&eua.v[2]) == g_ia4.v4.s_addr);
-       OSMO_ASSERT(!memcmp(&eua.v[6], &g_ia6.v6, 16));
-}
-
-static void test_in46a_from_eua_v6(void)
-{
-       struct in46_addr ia[2];
-       struct ul66_t eua;
-       const uint8_t v6_unspec[] = { PDP_EUA_ORG_IETF, PDP_EUA_TYPE_v6 };
-       const uint8_t v6_spec[] = { PDP_EUA_ORG_IETF, PDP_EUA_TYPE_v6,
-                                   
1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf,0x10 };
-
-       memset(&eua, 0, sizeof(eua));
-
-       printf("Testing in46a_from_eua() with IPv6 addresses\n");
-
-       /* unspecified V6 */
-       memcpy(eua.v, v6_unspec, sizeof(v6_unspec));
-       eua.l = sizeof(v6_unspec);
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) == 1);
-       OSMO_ASSERT(ia[0].len == 16);
-       OSMO_ASSERT(IN6_IS_ADDR_UNSPECIFIED(&ia[0].v6));
-
-       /* specified V6 */
-       memcpy(eua.v, v6_spec, sizeof(v6_spec));
-       eua.l = sizeof(v6_spec);
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) == 1);
-       OSMO_ASSERT(ia[0].len == 16);
-       OSMO_ASSERT(!memcmp(&ia[0].v6, v6_spec+2, ia[0].len));
-}
-
-static void test_in46a_from_eua_v4v6(void) {
-       struct in46_addr ia[2];
-       struct ul66_t eua;
-       const uint8_t v4_unspec_v6_unspec[] = { PDP_EUA_ORG_IETF, 
PDP_EUA_TYPE_v4v6 };
-       const uint8_t v4_spec_v6_unspec[] = { PDP_EUA_ORG_IETF, 
PDP_EUA_TYPE_v4v6, 1,2,3,4 };
-       const uint8_t v4_unspec_v6_spec[] = { PDP_EUA_ORG_IETF, 
PDP_EUA_TYPE_v4v6, 1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf,0x10 };
-       const uint8_t v4_spec_v6_spec[] = { PDP_EUA_ORG_IETF, 
PDP_EUA_TYPE_v4v6, 1,2,3,4, 1,2,3,4,5,6,7,8,9,0xa,0xb,0xc,0xd,0xe,0xf,0x10 };
-
-       memset(&eua, 0, sizeof(eua));
-
-       printf("Testing in46a_from_eua() with IPv4v6 addresses\n");
-
-       /* unspecified V4 & V6 */
-       memcpy(eua.v, v4_unspec_v6_unspec, sizeof(v4_unspec_v6_unspec));
-       eua.l = sizeof(v4_unspec_v6_unspec);
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) == 2);
-       OSMO_ASSERT(ia[0].len == 4);
-       OSMO_ASSERT(ia[1].len == 16);
-       OSMO_ASSERT(ia[0].v4.s_addr == 0);
-       OSMO_ASSERT(IN6_IS_ADDR_UNSPECIFIED(&ia[1].v6));
-
-       /* specified V4, unspecified V6 */
-       memcpy(eua.v, v4_spec_v6_unspec, sizeof(v4_spec_v6_unspec));
-       eua.l = sizeof(v4_spec_v6_unspec);
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) == 2);
-       OSMO_ASSERT(ia[0].len == 4);
-       OSMO_ASSERT(ia[1].len == 16);
-       OSMO_ASSERT(ia[0].v4.s_addr == htonl(0x01020304));
-       OSMO_ASSERT(IN6_IS_ADDR_UNSPECIFIED(&ia[1].v6));
-
-       /* unspecified V4, specified V6 */
-       memcpy(eua.v, v4_unspec_v6_spec, sizeof(v4_unspec_v6_spec));
-       eua.l = sizeof(v4_unspec_v6_spec);
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) == 2);
-       OSMO_ASSERT(ia[0].len == 4);
-       OSMO_ASSERT(ia[1].len == 16);
-       OSMO_ASSERT(ia[0].v4.s_addr == 0);
-       OSMO_ASSERT(!memcmp(&ia[1].v6, v4_unspec_v6_spec+2, ia[1].len));
-
-       /* specified V4, specified V6 */
-       memcpy(eua.v, v4_spec_v6_spec, sizeof(v4_spec_v6_spec));
-       eua.l = sizeof(v4_spec_v6_spec);
-       OSMO_ASSERT(in46a_from_eua(&eua, ia) == 2);
-       OSMO_ASSERT(ia[0].len == 4);
-       OSMO_ASSERT(ia[1].len == 16);
-       OSMO_ASSERT(ia[0].v4.s_addr == htonl(0x01020304));
-       OSMO_ASSERT(!memcmp(&ia[1].v6, v4_spec_v6_spec+6, ia[1].len));
-}
-
-static void test_in46a_netmasklen_v6(void)
-{
-       unsigned int len;
-       printf("Testing in46a_netmasklen() with IPv6 addresses\n");
-       const struct in46_addr netmaskA = {
-               .len = 16,
-               .v6.s6_addr = 
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
-       };
-       len = in46a_netmasklen(&netmaskA);
-       OSMO_ASSERT(len == 128);
-
-       const struct in46_addr netmaskB = {
-               .len = 16,
-               .v6.s6_addr = 
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00},
-       };
-       len = in46a_netmasklen(&netmaskB);
-       OSMO_ASSERT(len == 104);
-
-       const struct in46_addr netmaskC = {
-               .len = 16,
-               .v6.s6_addr = 
{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00},
-       };
-       len = in46a_netmasklen(&netmaskC);
-       OSMO_ASSERT(len == 103);
-
-       const struct in46_addr netmaskD = {
-               .len = 16,
-               .v6.s6_addr = 
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-       };
-       len = in46a_netmasklen(&netmaskD);
-       OSMO_ASSERT(len == 0);
-}
-
-int main(int argc, char **argv)
-{
-       void *tall_ctx = talloc_named_const(NULL, 1, "Root context");
-       msgb_talloc_ctx_init(tall_ctx, 0);
-       osmo_init_logging2(tall_ctx, &log_info);
-       log_set_use_color(osmo_stderr_target, 0);
-       log_set_print_filename2(osmo_stderr_target, LOG_FILENAME_NONE);
-
-       srand(time(NULL));
-
-       if (argc < 2 || strcmp(argv[1], "-v6")) {
-               test_in46a_to_af();
-               test_in46a_to_sas();
-               test_in46a_ntop();
-               test_in46p_ntoa();
-               test_in46a_equal();
-               test_in46a_within_mask();
-               test_in46a_to_eua();
-               test_in46a_from_eua();
-               test_in46a_netmasklen();
-       } else {
-               test_in46a_to_af_v6();
-               test_in46a_to_sas_v6();
-               test_in46a_ntop_v6();
-               test_in46a_equal_v6();
-               test_in46a_to_eua_v6();
-               test_in46a_from_eua_v6();
-               test_in46a_to_eua_v4v6();
-               test_in46a_from_eua_v4v6();
-               test_in46a_netmasklen_v6();
-       }
-       return 0;
-}
diff --git a/tests/lib/in46a_test.ok b/tests/lib/in46a_test.ok
deleted file mode 100644
index b497ad1..0000000
--- a/tests/lib/in46a_test.ok
+++ /dev/null
@@ -1,17 +0,0 @@
-Testing in46a_to_af() with IPv4 addresses
-Testing in46a_to_sas() with IPv4 addresses
-Testing in46a_ntop() with IPv4 addresses
-res = UNDEFINED
-res = UNDEFINED
-res = 1.2.3.4
-in46p_ntoa() returns 16.32.48.0/24
-Testing in46a_equal() with IPv4 addresses
-Testing in46a_within_mask() with IPv4 addresses
-in46a_within_mask(10.11.12.13, 10.11.12.13, 32) = 1
-in46a_within_mask(10.11.12.13, 10.11.12.12, 30) = 1
-in46a_within_mask(10.11.12.13, 10.8.0.0, 13) = 1
-in46a_within_mask(10.11.12.14, 10.11.12.13, 32) = 0
-in46a_within_mask(10.11.12.14, 10.11.12.12, 30) = 1
-testing in46a_to_eua() with IPv4 addresses
-Testing in46a_from_eua() with IPv4 addresses
-Testing in46a_netmasklen() with IPv4 addresses
diff --git a/tests/lib/in46a_v6_test.ok b/tests/lib/in46a_v6_test.ok
deleted file mode 100644
index 10dc7f4..0000000
--- a/tests/lib/in46a_v6_test.ok
+++ /dev/null
@@ -1,10 +0,0 @@
-Testing in46a_to_af() with IPv6 addresses
-Testing in46a_to_sas() with IPv6 addresses
-Testing in46a_ntop() with IPv6 addresses
-res = 102:304:506:708:90a:b0c:d0e:f10
-Testing in46a_equal() with IPv6 addresses
-Testing in46a_to_eua() with IPv6 addresses
-Testing in46a_from_eua() with IPv6 addresses
-Testing in46a_to_eua() with IPv4v6 addresses
-Testing in46a_from_eua() with IPv4v6 addresses
-Testing in46a_netmasklen() with IPv6 addresses
diff --git a/tests/lib/ippool_test.c b/tests/lib/ippool_test.c
index 2af4a38..17f8fed 100644
--- a/tests/lib/ippool_test.c
+++ b/tests/lib/ippool_test.c
@@ -8,8 +8,8 @@
 #include <osmocom/core/application.h>
 #include <osmocom/core/logging.h>
 #include <osmocom/core/msgb.h>
+#include <osmocom/core/in46_addr.h>

-#include "../../lib/in46_addr.h"
 #include "../../lib/ippool.h"
 #include "../../lib/syserr.h"

diff --git a/tests/testsuite.at b/tests/testsuite.at
index 2602a3a..5ba99cb 100644
--- a/tests/testsuite.at
+++ b/tests/testsuite.at
@@ -15,18 +15,6 @@
 AT_CHECK([$abs_top_builddir/tests/lib/ippool_test -v6], [], [expout], [experr])
 AT_CLEANUP

-AT_SETUP([in46a])
-AT_KEYWORDS([in46a])
-cat $abs_srcdir/lib/in46a_test.ok > expout
-AT_CHECK([$abs_top_builddir/tests/lib/in46a_test], [], [expout], [])
-AT_CLEANUP
-
-AT_SETUP([in46a_v6])
-AT_KEYWORDS([in46a_v6])
-cat $abs_srcdir/lib/in46a_v6_test.ok > expout
-AT_CHECK([$abs_top_builddir/tests/lib/in46a_test -v6], [], [expout], [])
-AT_CLEANUP
-
 AT_SETUP([gtpie])
 AT_KEYWORDS([gtpie])
 cat $abs_srcdir/gtp/gtpie_test.ok > expout

--
To view, visit https://gerrit.osmocom.org/c/osmo-ggsn/+/36070?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ggsn
Gerrit-Branch: master
Gerrit-Change-Id: I8f4d9d78689909a149683583cfe36bcdc3f7cbc7
Gerrit-Change-Number: 36070
Gerrit-PatchSet: 1
Gerrit-Owner: osmith <osm...@sysmocom.de>
Gerrit-MessageType: newchange

Reply via email to