aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/gtp-kernel.c17
-rw-r--r--lib/in46_addr.c6
-rw-r--r--lib/in46_addr.h8
-rw-r--r--lib/util.c35
-rw-r--r--lib/util.h18
6 files changed, 81 insertions, 7 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index b6e7aba..533d777 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,10 +1,10 @@
noinst_LIBRARIES = libmisc.a
-noinst_HEADERS = gnugetopt.h ippool.h lookup.h syserr.h tun.h in46_addr.h netdev.h gtp-kernel.h
+noinst_HEADERS = gnugetopt.h ippool.h lookup.h syserr.h tun.h in46_addr.h netdev.h gtp-kernel.h util.h
AM_CFLAGS = -O2 -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb $(LIBOSMOCORE_CFLAGS)
-libmisc_a_SOURCES = getopt1.c getopt.c ippool.c lookup.c tun.c debug.c in46_addr.c netdev.c
+libmisc_a_SOURCES = getopt1.c getopt.c ippool.c lookup.c tun.c debug.c in46_addr.c netdev.c util.c
if ENABLE_GTP_KERNEL
AM_CFLAGS += -DGTP_KERNEL $(LIBGTPNL_CFLAGS)
diff --git a/lib/gtp-kernel.c b/lib/gtp-kernel.c
index 48811bc..f6df408 100644
--- a/lib/gtp-kernel.c
+++ b/lib/gtp-kernel.c
@@ -26,6 +26,8 @@
#include "../lib/tun.h"
#include "../lib/syserr.h"
+#include "../lib/util.h"
+#include "../lib/ippool.h"
#include "../gtp/pdp.h"
#include "../gtp/gtp.h"
@@ -37,16 +39,23 @@
static void pdp_debug(const char *prefix, const char *devname, struct pdp_t *pdp)
{
- struct in46_addr ia46;
+ char buf4[INET_ADDRSTRLEN], buf6[INET6_ADDRSTRLEN];
+ struct ippoolm_t *peer;
struct in_addr ia;
- in46a_from_eua(&pdp->eua, &ia46);
+ buf4[0] = '\0';
+ if ((peer = pdp_get_peer_ipv(pdp, false)))
+ in46a_ntop(&peer->addr, buf4, sizeof(buf4));
+ buf6[0] = '\0';
+ if ((peer = pdp_get_peer_ipv(pdp, true)))
+ in46a_ntop(&peer->addr, buf6, sizeof(buf6));
+
gsna2in_addr(&ia, &pdp->gsnrc);
- LOGPDPX(DGGSN, LOGL_DEBUG, pdp, "%s %s v%u TEID %"PRIx64" EUA=%s SGSN=%s\n", prefix,
+ LOGPDPX(DGGSN, LOGL_DEBUG, pdp, "%s %s v%u TEID %"PRIx64" EUA=(%s,%s) SGSN=%s\n", prefix,
devname, pdp->version,
pdp->version == 0 ? pdp_gettid(pdp->imsi, pdp->nsapi) : pdp->teid_gn,
- in46a_ntoa(&ia46), inet_ntoa(ia));
+ buf4, buf6, inet_ntoa(ia));
}
static struct {
diff --git a/lib/in46_addr.c b/lib/in46_addr.c
index f4bb8a2..2562c71 100644
--- a/lib/in46_addr.c
+++ b/lib/in46_addr.c
@@ -60,7 +60,11 @@ int in46a_to_sas(struct sockaddr_storage *out, const struct in46_addr *in)
return 0;
}
-/*! Convenience wrapper around inet_ntop() for \ref in46_addr */
+/*! 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;
diff --git a/lib/in46_addr.h b/lib/in46_addr.h
index e4654cc..153df00 100644
--- a/lib/in46_addr.h
+++ b/lib/in46_addr.h
@@ -31,3 +31,11 @@ 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/util.c b/lib/util.c
new file mode 100644
index 0000000..6bb0d85
--- /dev/null
+++ b/lib/util.c
@@ -0,0 +1,35 @@
+/*
+ * misc helpers
+ * Copyright 2019 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * 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 "../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.
+* \param[in] v4v6 IP version to select. Valid values are 4 and 6.
+* \returns The selected peer matching the given IP version. NULL if not present.
+*/
+struct ippoolm_t *pdp_get_peer_ipv(struct pdp_t *pdp, bool is_ipv6) {
+ uint8_t i;
+
+ for (i = 0; i < 2; i++) {
+ struct ippoolm_t * ippool = pdp->peer[i];
+ if (!ippool)
+ continue;
+ if (is_ipv6 && in46a_is_v6(&ippool->addr))
+ return ippool;
+ else if (!is_ipv6 && in46a_is_v4(&ippool->addr))
+ return ippool;
+ }
+ return NULL;
+}
diff --git a/lib/util.h b/lib/util.h
new file mode 100644
index 0000000..bc9674d
--- /dev/null
+++ b/lib/util.h
@@ -0,0 +1,18 @@
+#pragma once
+/*
+ * misc helpers
+ * Copyright 2019 sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
+ *
+ * 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 <stdbool.h>
+
+struct ippoolm_t;
+struct pdp_t;
+
+struct ippoolm_t *pdp_get_peer_ipv(struct pdp_t *pdp, bool is_ipv6);