diff --git a/Makefile b/Makefile
index eb07143..9081679 100644
--- a/Makefile
+++ b/Makefile
@@ -5,8 +5,5 @@ obj-m += gtp.o
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
- $(CC) -lmnl gtp-link-add.c -o gtp-link-add
- $(CC) -lmnl gtp-tunnel.c genl.c gtpnl.c -o gtp-tunnel
clean:
rm -rf *.o *.mod.* modules.order Module.symvers *.ko .tmp_versions .*.cmd
- rm -f genl-family-get gtp-link-add gtp-tunnel-add
diff --git a/libgtnl/.gitignore b/libgtnl/.gitignore
new file mode 100644
index 0000000..9deb3b5
--- /dev/null
+++ b/libgtnl/.gitignore
@@ -0,0 +1,23 @@
+# Dependency and object files
+.*.d
+*.o
+*.lo
+*.la
+.deps
+.libs
+.dirstamp
+
+# Generated by autoconf/configure
+Makefile
+Makefile.in
+config.*
+configure
+autom4te.cache
+stamp-h1
+aclocal.m4
+libgtpnl.pc
+libtool
+build-aux
+
+# Debian package build temporary files
+build-stamp
diff --git a/libgtnl/Make_global.am b/libgtnl/Make_global.am
new file mode 100644
index 0000000..1654f10
--- /dev/null
+++ b/libgtnl/Make_global.am
@@ -0,0 +1,24 @@
+# This is _NOT_ the library release version, it's an API version.
+# Extracted from Chapter 6 "Library interface versions" of the libtool docs.
+#
+#
+# Here are a set of rules to help you update your library version information:
+#
+# 1. Start with version information of `0:0:0' for each libtool library.
+# 2. Update the version information only immediately before a public release
+# of your software. More frequent updates are unnecessary, and only guarantee
+# that the current interface number gets larger faster.
+# 3. If the library source code has changed at all since the last update,
+# then increment revision (`c:r:a' becomes `c:r+1:a').
+# 4. If any interfaces have been added, removed, or changed since the last
+# update, increment current, and set revision to 0.
+# 5. If any interfaces have been added since the last public release, then
+# increment age.
+# 6. If any interfaces have been removed since the last public release, then
+# set age to 0.
+#
+#
+LIBVERSION=0:0:0
+
+AM_CPPFLAGS = ${regular_CPPFLAGS} -I${top_srcdir}/include ${LIBMNL_CFLAGS}
+AM_CFLAGS = ${regular_CFLAGS} ${GCC_FVISIBILITY_HIDDEN}
diff --git a/libgtnl/Makefile.am b/libgtnl/Makefile.am
new file mode 100644
index 0000000..cb72faf
--- /dev/null
+++ b/libgtnl/Makefile.am
@@ -0,0 +1,11 @@
+include $(top_srcdir)/Make_global.am
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = src include tools
+DIST_SUBDIRS = src include tools
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libgtpnl.pc
+
+${pkgconfig_DATA}: ${top_builddir}/config.status
diff --git a/libgtnl/configure.ac b/libgtnl/configure.ac
new file mode 100644
index 0000000..a9845ac
--- /dev/null
+++ b/libgtnl/configure.ac
@@ -0,0 +1,34 @@
+dnl Process this file with autoconf to create configure.
+
+AC_INIT([libgtpnl], [1.0.0])
+AC_CONFIG_AUX_DIR([build-aux])
+AC_CANONICAL_HOST
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_HEADERS([config.h])
+AM_INIT_AUTOMAKE([foreign tar-pax no-dist-gzip dist-bzip2 1.6 subdir-objects])
+
+dnl kernel style compile messages
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+dnl Dependencies
+PKG_CHECK_MODULES([LIBMNL], [libmnl >= 1.0.0])
+
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_EXEEXT
+AC_DISABLE_STATIC
+LT_INIT
+CHECK_GCC_FVISIBILITY
+case "$host" in
+*-*-linux* | *-*-uclinux*) ;;
+*) AC_MSG_ERROR([Linux only, dude!]);;
+esac
+
+regular_CPPFLAGS="-D_FILE_OFFSET_BITS=64 -D_REENTRANT"
+regular_CFLAGS="-Wall -Waggregate-return -Wmissing-declarations \
+ -Wmissing-prototypes -Wshadow -Wstrict-prototypes \
+ -Wformat=2 -pipe"
+AC_SUBST([regular_CPPFLAGS])
+AC_SUBST([regular_CFLAGS])
+AC_CONFIG_FILES([Makefile src/Makefile include/Makefile include/libgtpnl/Makefile include/linux/Makefile tools/Makefile libgtpnl.pc])
+AC_OUTPUT
diff --git a/libgtnl/include/Makefile.am b/libgtnl/include/Makefile.am
new file mode 100644
index 0000000..bafe5e3
--- /dev/null
+++ b/libgtnl/include/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = libgtpnl linux
diff --git a/libgtnl/include/libgtpnl/Makefile.am b/libgtnl/include/libgtpnl/Makefile.am
new file mode 100644
index 0000000..b1c2bee
--- /dev/null
+++ b/libgtnl/include/libgtpnl/Makefile.am
@@ -0,0 +1 @@
+pkginclude_HEADERS = gtpnl.h
diff --git a/libgtnl/include/libgtpnl/gtpnl.h b/libgtnl/include/libgtpnl/gtpnl.h
new file mode 100644
index 0000000..00a60d8
--- /dev/null
+++ b/libgtnl/include/libgtpnl/gtpnl.h
@@ -0,0 +1,26 @@
+#ifndef _LIBGTPNL_H_
+#define _LIBGTPNL_H_
+
+#include
+
+struct mnl_socket;
+struct nlmsghdr;
+
+struct mnl_socket *genl_socket_open(void);
+struct nlmsghdr *genl_nlmsg_build_hdr(char *buf, uint16_t type, uint16_t flags,
+ uint32_t seq, uint8_t cmd);
+int genl_socket_talk(struct mnl_socket *nl, struct nlmsghdr *nlh, uint32_t seq,
+ int (*cb)(const struct nlmsghdr *nlh, void *data),
+ void *data);
+int genl_lookup_family(struct mnl_socket *nl, const char *family);
+
+int gtp_dev_create(const char *ifname);
+
+int gtp_add_tunnel(int genl_id, struct mnl_socket *nl, const char *ifname,
+ const char *ms_addr, const char *sgsn_addr, uint64_t tid,
+ int gtp_version);
+int gtp_del_tunnel(int genl_id, struct mnl_socket *nl, const char *ifname,
+ uint64_t tid, uint32_t gtp_version);
+int gtp_list_tunnel(int genl_id, struct mnl_socket *nl);
+
+#endif
diff --git a/libgtnl/include/linux/Makefile.am b/libgtnl/include/linux/Makefile.am
new file mode 100644
index 0000000..082198e
--- /dev/null
+++ b/libgtnl/include/linux/Makefile.am
@@ -0,0 +1 @@
+noinst_HEADERS = gtp_nl.h
diff --git a/libgtnl/include/linux/gtp_nl.h b/libgtnl/include/linux/gtp_nl.h
new file mode 100644
index 0000000..968824c
--- /dev/null
+++ b/libgtnl/include/linux/gtp_nl.h
@@ -0,0 +1,45 @@
+#ifndef _UAPI_LINUX_GTP_H_
+#define _UAPI_LINUX_GTP_H__
+
+enum {
+ IFLA_GTP_UNSPEC,
+ IFLA_GTP_LOCAL_ADDR_IPV4,
+ IFLA_GTP_HASHSIZE,
+ __IFLA_GTP_MAX,
+};
+#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
+
+enum gtp_genl_cmds {
+ GTP_CMD_TUNNEL_NEW,
+ GTP_CMD_TUNNEL_DELETE,
+ GTP_CMD_TUNNEL_GET,
+
+ GTP_CMD_TUNNEL_MAX,
+};
+
+enum gtp_version {
+ GTP_V0 = 0,
+ GTP_V1,
+};
+
+enum gtp_cfg_attrs {
+ GTPA_CFG_UNSPEC = 0,
+ GTPA_CFG_LINK,
+ GTPA_CFG_LOCAL_ADDR_IPV4,
+ GTPA_CFG_HSIZE,
+ __GTPA_CFG_MAX,
+};
+#define GTPA_CFG_MAX (__GTPA_CFG_MAX + 1)
+
+enum gtp_attrs {
+ GTPA_UNSPEC = 0,
+ GTPA_LINK,
+ GTPA_VERSION,
+ GTPA_TID, /* 64 bits for GTPv1 */
+ GTPA_SGSN_ADDRESS,
+ GTPA_MS_ADDRESS,
+ __GTPA_MAX,
+};
+#define GTPA_MAX (__GTPA_MAX + 1)
+
+#endif /* _UAPI_LINUX_GTP_H_ */
diff --git a/libgtnl/libgtpnl.pc.in b/libgtnl/libgtpnl.pc.in
new file mode 100644
index 0000000..2dad5fe
--- /dev/null
+++ b/libgtnl/libgtpnl.pc.in
@@ -0,0 +1,15 @@
+# libgtpnl pkg-config file
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libgtpnl
+Description: Netlink library for GTP Linux kernel implementation
+URL: http://git.osmocom.org/libgtpnl/
+Version: @VERSION@
+Requires:
+Conflicts:
+Libs: -L${libdir} -lgtpnl
+Cflags: -I${includedir}
diff --git a/libgtnl/m4/gcc4_visibility.m4 b/libgtnl/m4/gcc4_visibility.m4
new file mode 100644
index 0000000..214d3f3
--- /dev/null
+++ b/libgtnl/m4/gcc4_visibility.m4
@@ -0,0 +1,21 @@
+
+# GCC 4.x -fvisibility=hidden
+
+AC_DEFUN([CHECK_GCC_FVISIBILITY], [
+ AC_LANG_PUSH([C])
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$saved_CFLAGS -fvisibility=hidden"
+ AC_CACHE_CHECK([whether compiler accepts -fvisibility=hidden],
+ [ac_cv_fvisibility_hidden], AC_COMPILE_IFELSE(
+ [AC_LANG_SOURCE()],
+ [ac_cv_fvisibility_hidden=yes],
+ [ac_cv_fvisibility_hidden=no]
+ ))
+ if test "$ac_cv_fvisibility_hidden" = "yes"; then
+ AC_DEFINE([HAVE_VISIBILITY_HIDDEN], [1],
+ [True if compiler supports -fvisibility=hidden])
+ AC_SUBST([GCC_FVISIBILITY_HIDDEN], [-fvisibility=hidden])
+ fi
+ CFLAGS="$saved_CFLAGS"
+ AC_LANG_POP([C])
+])
diff --git a/libgtnl/src/Makefile.am b/libgtnl/src/Makefile.am
new file mode 100644
index 0000000..a9b072f
--- /dev/null
+++ b/libgtnl/src/Makefile.am
@@ -0,0 +1,5 @@
+include $(top_srcdir)/Make_global.am
+lib_LTLIBRARIES = libgtpnl.la
+
+libgtpnl_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libgtpnl.map -version-info $(LIBVERSION)
+libgtpnl_la_SOURCES = genl.c gtp-genl.c gtp-rtnl.c libgtpnl.map
diff --git a/genl.c b/libgtnl/src/genl.c
similarity index 94%
rename from genl.c
rename to libgtnl/src/genl.c
index a89d6cf..099b317 100644
--- a/genl.c
+++ b/libgtnl/src/genl.c
@@ -6,6 +6,10 @@
#include
#include
+#include
+
+#include "internal.h"
+
struct nlmsghdr *
genl_nlmsg_build_hdr(char *buf, uint16_t type, uint16_t flags, uint32_t seq,
uint8_t cmd)
@@ -24,6 +28,7 @@ genl_nlmsg_build_hdr(char *buf, uint16_t type, uint16_t flags, uint32_t seq,
return nlh;
}
+EXPORT_SYMBOL(genl_nlmsg_build_hdr);
static int genl_ctrl_validate_cb(const struct nlattr *attr, void *data)
{
@@ -77,6 +82,7 @@ struct mnl_socket *genl_socket_open(void)
return nl;
}
+EXPORT_SYMBOL(genl_socket_open);
int genl_socket_talk(struct mnl_socket *nl, struct nlmsghdr *nlh, uint32_t seq,
int (*cb)(const struct nlmsghdr *nlh, void *data),
@@ -101,6 +107,7 @@ int genl_socket_talk(struct mnl_socket *nl, struct nlmsghdr *nlh, uint32_t seq,
return ret;
}
+EXPORT_SYMBOL(genl_socket_talk);
static struct nlmsghdr *
genl_nlmsg_build_lookup(char *buf, const char *subsys_name)
@@ -136,3 +143,4 @@ int genl_lookup_family(struct mnl_socket *nl, const char *family)
return genl_id;
}
+EXPORT_SYMBOL(genl_lookup_family);
diff --git a/libgtnl/src/gtp-genl.c b/libgtnl/src/gtp-genl.c
new file mode 100644
index 0000000..0dd5473
--- /dev/null
+++ b/libgtnl/src/gtp-genl.c
@@ -0,0 +1,177 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+#include
+#include
+
+#include "internal.h"
+
+static void gtp_build_payload(struct nlmsghdr *nlh, uint64_t tid,
+ uint32_t ifidx, uint32_t sgsn_addr,
+ uint32_t ms_addr, uint32_t version)
+{
+ mnl_attr_put_u32(nlh, GTPA_VERSION, version);
+ mnl_attr_put_u32(nlh, GTPA_LINK, ifidx);
+ mnl_attr_put_u32(nlh, GTPA_SGSN_ADDRESS, sgsn_addr);
+ mnl_attr_put_u32(nlh, GTPA_MS_ADDRESS, ms_addr);
+ mnl_attr_put_u64(nlh, GTPA_TID, tid);
+}
+
+int gtp_add_tunnel(int genl_id, struct mnl_socket *nl, const char *ifname,
+ const char *ms_addr, const char *sgsn_addr, uint64_t tid,
+ int gtp_version)
+{
+ uint32_t gtp_ifidx;
+ struct in_addr ms, sgsn;
+ struct nlmsghdr *nlh;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ uint32_t seq = time(NULL);
+
+ gtp_ifidx = if_nametoindex(ifname);
+ if (gtp_ifidx == 0){
+ fprintf(stderr, "wrong GTP interface %s\n", ifname);
+ return -1;
+ }
+
+ if (inet_aton(ms_addr, &ms) < 0) {
+ perror("bad address for ms");
+ return -1;
+ }
+
+ if (inet_aton(sgsn_addr, &sgsn) < 0) {
+ perror("bad address for sgsn");
+ return -1;
+ }
+
+ if (gtp_version > GTP_V1) {
+ fprintf(stderr, "wrong GTP version %u, use v0 or v1\n",
+ gtp_version);
+ return -1;
+ }
+
+ nlh = genl_nlmsg_build_hdr(buf, genl_id, NLM_F_EXCL | NLM_F_ACK, ++seq,
+ GTP_CMD_TUNNEL_NEW);
+ gtp_build_payload(nlh, tid, gtp_ifidx, sgsn.s_addr,
+ ms.s_addr, gtp_version);
+
+ if (genl_socket_talk(nl, nlh, seq, NULL, NULL) < 0)
+ perror("genl_socket_talk");
+
+ return 0;
+}
+EXPORT_SYMBOL(gtp_add_tunnel);
+
+int gtp_del_tunnel(int genl_id, struct mnl_socket *nl, const char *ifname,
+ uint64_t tid, uint32_t gtp_version)
+{
+ uint32_t gtp_ifidx;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ uint32_t seq = time(NULL);
+
+ gtp_ifidx = if_nametoindex(ifname);
+
+ nlh = genl_nlmsg_build_hdr(buf, genl_id, NLM_F_ACK, ++seq,
+ GTP_CMD_TUNNEL_DELETE);
+ gtp_build_payload(nlh, tid, gtp_ifidx, 0, 0, gtp_version);
+
+ if (genl_socket_talk(nl, nlh, seq, NULL, NULL) < 0)
+ perror("genl_socket_talk");
+
+ return 0;
+}
+EXPORT_SYMBOL(gtp_del_tunnel);
+
+struct gtp_pdp {
+ uint32_t version;
+ uint64_t tid;
+ struct in_addr sgsn_addr;
+ struct in_addr ms_addr;
+};
+
+static int genl_gtp_validate_cb(const struct nlattr *attr, void *data)
+{
+ const struct nlattr **tb = data;
+ int type = mnl_attr_get_type(attr);
+
+ if (mnl_attr_type_valid(attr, CTRL_ATTR_MAX) < 0)
+ return MNL_CB_OK;
+
+ switch(type) {
+ case GTPA_TID:
+ if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ case GTPA_SGSN_ADDRESS:
+ case GTPA_MS_ADDRESS:
+ case GTPA_VERSION:
+ if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) {
+ perror("mnl_attr_validate");
+ return MNL_CB_ERROR;
+ }
+ break;
+ default:
+ break;
+ }
+ tb[type] = attr;
+ return MNL_CB_OK;
+}
+
+static int genl_gtp_attr_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct nlattr *tb[GTPA_MAX + 1] = {};
+ struct gtp_pdp pdp;
+ struct genlmsghdr *genl;
+
+ mnl_attr_parse(nlh, sizeof(*genl), genl_gtp_validate_cb, tb);
+ if (tb[GTPA_TID])
+ pdp.tid = mnl_attr_get_u64(tb[GTPA_TID]);
+ if (tb[GTPA_SGSN_ADDRESS]) {
+ pdp.sgsn_addr.s_addr =
+ mnl_attr_get_u32(tb[GTPA_SGSN_ADDRESS]);
+ }
+ if (tb[GTPA_MS_ADDRESS]) {
+ pdp.ms_addr.s_addr = mnl_attr_get_u32(tb[GTPA_MS_ADDRESS]);
+ }
+ if (tb[GTPA_VERSION]) {
+ pdp.version = mnl_attr_get_u32(tb[GTPA_VERSION]);
+ }
+
+ printf("version %u ", pdp.version);
+ printf("tid %"PRIu64" ms_addr %s ", pdp.tid, inet_ntoa(pdp.sgsn_addr));
+ printf("sgsn_addr %s\n", inet_ntoa(pdp.ms_addr));
+
+ return MNL_CB_OK;
+}
+
+int gtp_list_tunnel(int genl_id, struct mnl_socket *nl)
+{
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ uint32_t seq = time(NULL);
+
+ nlh = genl_nlmsg_build_hdr(buf, genl_id, NLM_F_DUMP, 0,
+ GTP_CMD_TUNNEL_GET);
+
+ if (genl_socket_talk(nl, nlh, seq, genl_gtp_attr_cb, NULL) < 0) {
+ perror("genl_socket_talk");
+ return 0;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(gtp_list_tunnel);
diff --git a/libgtnl/src/gtp-rtnl.c b/libgtnl/src/gtp-rtnl.c
new file mode 100644
index 0000000..2cd43ef
--- /dev/null
+++ b/libgtnl/src/gtp-rtnl.c
@@ -0,0 +1,82 @@
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+
+#include "internal.h"
+
+int gtp_dev_create(const char *ifname)
+{
+ struct mnl_socket *nl;
+ char buf[MNL_SOCKET_BUFFER_SIZE];
+ struct nlmsghdr *nlh;
+ struct ifinfomsg *ifm;
+ int ret;
+ unsigned int seq, portid;
+ struct nlattr *nest, *nest2;
+
+ nlh = mnl_nlmsg_put_header(buf);
+ nlh->nlmsg_type = RTM_NEWLINK;
+ nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_ACK;
+ nlh->nlmsg_seq = seq = time(NULL);
+ ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
+ ifm->ifi_family = AF_INET;
+ ifm->ifi_change |= IFF_UP;
+ ifm->ifi_flags |= IFF_UP;
+
+ mnl_attr_put_u32(nlh, IFLA_LINK, if_nametoindex(ifname));
+ nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
+ mnl_attr_put_str(nlh, IFLA_INFO_KIND, "gtp");
+ nest2 = mnl_attr_nest_start(nlh, IFLA_INFO_DATA);
+ mnl_attr_put_u32(nlh, IFLA_GTP_LOCAL_ADDR_IPV4, 0);
+ mnl_attr_put_u32(nlh, IFLA_GTP_HASHSIZE, 131072);
+ mnl_attr_nest_end(nlh, nest2);
+ mnl_attr_nest_end(nlh, nest);
+
+ nl = mnl_socket_open(NETLINK_ROUTE);
+ if (nl == NULL) {
+ perror("mnl_socket_open");
+ return -1;
+ }
+
+ if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
+ perror("mnl_socket_bind");
+ return -1;
+ }
+ portid = mnl_socket_get_portid(nl);
+
+ mnl_nlmsg_fprintf(stdout, nlh, nlh->nlmsg_len,
+ sizeof(struct ifinfomsg));
+
+ if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) {
+ perror("mnl_socket_send");
+ return -1;
+ }
+
+ ret = mnl_socket_recvfrom(nl, buf, sizeof(buf));
+ if (ret == -1) {
+ perror("read");
+ return -1;
+ }
+
+ ret = mnl_cb_run(buf, ret, seq, portid, NULL, NULL);
+ if (ret == -1){
+ perror("callback");
+ return -1;
+ }
+
+ mnl_socket_close(nl);
+
+ return 0;
+}
+EXPORT_SYMBOL(gtp_dev_create);
diff --git a/libgtnl/src/internal.h b/libgtnl/src/internal.h
new file mode 100644
index 0000000..3a88d1a
--- /dev/null
+++ b/libgtnl/src/internal.h
@@ -0,0 +1,12 @@
+#ifndef INTERNAL_H
+#define INTERNAL_H 1
+
+#include "config.h"
+#ifdef HAVE_VISIBILITY_HIDDEN
+# define __visible __attribute__((visibility("default")))
+# define EXPORT_SYMBOL(x) typeof(x) (x) __visible
+#else
+# define EXPORT_SYMBOL
+#endif
+
+#endif
diff --git a/libgtnl/src/libgtpnl.map b/libgtnl/src/libgtpnl.map
new file mode 100644
index 0000000..ead02e0
--- /dev/null
+++ b/libgtnl/src/libgtpnl.map
@@ -0,0 +1,13 @@
+LIBGTPNL_1.0 {
+global:
+ genl_socket_open;
+ genl_nlmsg_build_hdr;
+ genl_socket_talk;
+ genl_lookup_family;
+ gtp_dev_create;
+ gtp_add_tunnel;
+ gtp_del_tunnel;
+ gtp_list_tunnel;
+
+local: *;
+};
diff --git a/libgtnl/tools/Makefile.am b/libgtnl/tools/Makefile.am
new file mode 100644
index 0000000..7880f3c
--- /dev/null
+++ b/libgtnl/tools/Makefile.am
@@ -0,0 +1,10 @@
+include $(top_srcdir)/Make_global.am
+
+check_PROGRAMS = gtp-link-add \
+ gtp-tunnel
+
+gtp_link_add_SOURCES = gtp-link-add.c gtpnl.c
+gtp_link_add_LDADD = ../src/libgtpnl.la ${LIBMNL_LIBS}
+
+gtp_tunnel_SOURCES = gtp-tunnel.c gtpnl.c
+gtp_tunnel_LDADD = ../src/libgtpnl.la ${LIBMNL_LIBS}
diff --git a/gtp-link-add.c b/libgtnl/tools/gtp-link-add.c
similarity index 98%
rename from gtp-link-add.c
rename to libgtnl/tools/gtp-link-add.c
index 31f893e..c9c50c8 100644
--- a/gtp-link-add.c
+++ b/libgtnl/tools/gtp-link-add.c
@@ -9,7 +9,7 @@
#include
#include
-#include "gtp_nl.h"
+#include
int main(int argc, char *argv[])
{
diff --git a/gtp-tunnel.c b/libgtnl/tools/gtp-tunnel.c
similarity index 98%
rename from gtp-tunnel.c
rename to libgtnl/tools/gtp-tunnel.c
index aa405ad..ec091db 100644
--- a/gtp-tunnel.c
+++ b/libgtnl/tools/gtp-tunnel.c
@@ -10,8 +10,8 @@
#include
#include
-#include "gtp_nl.h"
-#include "genl.h"
+#include
+#include
static int
add_tunnel(int argc, char *argv[], int genl_id, struct mnl_socket *nl)
diff --git a/gtpnl.c b/libgtnl/tools/gtpnl.c
similarity index 94%
rename from gtpnl.c
rename to libgtnl/tools/gtpnl.c
index e98b9da..6b2f1e2 100644
--- a/gtpnl.c
+++ b/libgtnl/tools/gtpnl.c
@@ -1,6 +1,6 @@
#include
#include
-#include "gtp_nl.h"
+#include
void gtp_build_payload(struct nlmsghdr *nlh, uint64_t tid, uint32_t ifidx,
uint32_t sgsn_addr, uint32_t ms_addr, uint32_t version)