osmith has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/libgtpnl/+/35997?usp=email )


Change subject: gtp-link: allow to specify listener address
......................................................................

gtp-link: allow to specify listener address

   gtp-link add <device> <family> [--sgsn] [<address>]

Allow to specify listener address, if not specified use ANY_ADDRESS.

Change-Id: I7a9b64393fd68d58c2c158c0e85c0470be007f63
---
M tools/gtp-link.c
1 file changed, 67 insertions(+), 14 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/libgtpnl refs/changes/97/35997/1

diff --git a/tools/gtp-link.c b/tools/gtp-link.c
index 325a45f..83241ca 100644
--- a/tools/gtp-link.c
+++ b/tools/gtp-link.c
@@ -39,6 +39,7 @@
 #include <linux/if_link.h>

 #include <libgtpnl/gtpnl.h>
+#include <errno.h>

 struct gtp_server_sock {
        int                     family;
@@ -55,20 +56,26 @@
                        struct sockaddr_in6     in6;
                } fd2;
        } sockaddr;
+       union {
+               struct in_addr v4;
+               struct in6_addr v6;
+       } addr;
 };

-static void setup_sockaddr_in(struct sockaddr_in *sockaddr, uint16_t port)
+static void setup_sockaddr_in(struct sockaddr_in *sockaddr, struct in_addr *in,
+                             uint16_t port)
 {
        sockaddr->sin_family = AF_INET;
        sockaddr->sin_port = htons(port);
-       sockaddr->sin_addr.s_addr = INADDR_ANY;
+       sockaddr->sin_addr = *in;
 }

-static void setup_sockaddr_in6(struct sockaddr_in6 *sockaddr, uint16_t port)
+static void setup_sockaddr_in6(struct sockaddr_in6 *sockaddr, struct in6_addr 
*in6,
+                              uint16_t port)
 {
        sockaddr->sin6_family = AF_INET6;
        sockaddr->sin6_port = htons(port);
-       sockaddr->sin6_addr = in6addr_any;
+       sockaddr->sin6_addr = *in6;
 }

 static int setup_socket(struct gtp_server_sock *gtp_sock, int family)
@@ -80,8 +87,6 @@
        if (fd1 < 0 || fd2 < 0)
                return -1;

-       memset(gtp_sock, 0, sizeof(*gtp_sock));
-
        gtp_sock->family = family;
        gtp_sock->fd1 = fd1;
        gtp_sock->fd2 = fd2;
@@ -89,13 +94,17 @@
        switch (family) {
        case AF_INET:
                gtp_sock->len = sizeof(struct sockaddr_in);
-               setup_sockaddr_in(&gtp_sock->sockaddr.fd1.in, 3386);
-               setup_sockaddr_in(&gtp_sock->sockaddr.fd2.in, 2152);
+               setup_sockaddr_in(&gtp_sock->sockaddr.fd1.in,
+                                 &gtp_sock->addr.v4, 3386);
+               setup_sockaddr_in(&gtp_sock->sockaddr.fd2.in,
+                                 &gtp_sock->addr.v4, 2152);
                break;
        case AF_INET6:
                gtp_sock->len = sizeof(struct sockaddr_in6);
-               setup_sockaddr_in6(&gtp_sock->sockaddr.fd1.in6, 3386);
-               setup_sockaddr_in6(&gtp_sock->sockaddr.fd2.in6, 2152);
+               setup_sockaddr_in6(&gtp_sock->sockaddr.fd1.in6,
+                                  &gtp_sock->addr.v6, 3386);
+               setup_sockaddr_in6(&gtp_sock->sockaddr.fd2.in6,
+                                  &gtp_sock->addr.v6, 2152);
                if (setsockopt(fd1, IPPROTO_IPV6, IPV6_V6ONLY, &one, 
sizeof(one)) < 0)
                        perror("setsockopt IPV6_V6ONLY: ");
                if (setsockopt(fd2, IPPROTO_IPV6, IPV6_V6ONLY, &one, 
sizeof(one)) < 0)
@@ -111,9 +120,12 @@
        char buf[MNL_SOCKET_BUFFER_SIZE];
        struct gtp_server_sock gtp_sock;
        int ret, sgsn_mode = 0, family;
+       const char *addr = NULL;
+
+       memset(&gtp_sock, 0, sizeof(gtp_sock));

        if (argc < 3) {
-               printf("Usage: %s add <device> <family> [--sgsn]\n", argv[0]);
+               printf("Usage: %s add <device> <family> [--sgsn] <address>\n", 
argv[0]);
                printf("       %s del <device>\n", argv[0]);
                exit(EXIT_FAILURE);
        }
@@ -126,12 +138,23 @@
                return 0;
        } else if (!strcmp(argv[1], "add")) {
                if (argc < 4) {
-                       printf("Usage: %s add <device> <family> [--sgsn]\n", 
argv[0]);
+                       printf("Usage: %s add <device> <family> [--sgsn] 
<device>\n", argv[0]);
                        exit(EXIT_FAILURE);
                }

-               if (argc == 5 && !strcmp(argv[4], "--sgsn"))
-                       sgsn_mode = 1;
+               if (argc == 5) {
+                       if (!strcmp(argv[4], "--sgsn"))
+                               sgsn_mode = 1;
+                       else
+                               addr = argv[4];
+               }
+
+               if (argc == 6) {
+                       if (!strcmp(argv[4], "--sgsn"))
+                               sgsn_mode = 1;
+
+                       addr = argv[5];
+               }
        }

        if (!strcmp(argv[3], "ip"))
@@ -144,6 +167,23 @@
                exit(EXIT_FAILURE);
        }

+       if (addr) {
+               if (!inet_pton(family, addr, &gtp_sock.addr)) {
+                       fprintf(stderr, "invalid listener address: %s\n",
+                               strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
+       } else {
+               switch (family) {
+               case AF_INET:
+                       gtp_sock.addr.v4.s_addr = INADDR_ANY;
+                       break;
+               case AF_INET6:
+                       gtp_sock.addr.v6 = in6addr_any;
+                       break;
+               }
+       }
+
        if (setup_socket(&gtp_sock, family) < 0) {
                perror("socket");
                exit(EXIT_FAILURE);

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

Gerrit-Project: libgtpnl
Gerrit-Branch: master
Gerrit-Change-Id: I7a9b64393fd68d58c2c158c0e85c0470be007f63
Gerrit-Change-Number: 35997
Gerrit-PatchSet: 1
Gerrit-Owner: osmith <osm...@sysmocom.de>
Gerrit-MessageType: newchange

Reply via email to