blob: d342f2ba4b865ebe13e579f7a1c84f1dcf0615d8 [file] [log] [blame]
Harald Welte51b00a62014-04-03 09:37:38 -04001/* Command line utility to create GTP link */
2
3/* (C) 2014 by sysmocom - s.f.m.c. GmbH
Pablo Neira Ayuso448bce42016-05-08 21:43:40 +02004 * (C) 2016 by Pablo Neira Ayuso <pablo@netfilter.org>
5 *
Harald Welte51b00a62014-04-03 09:37:38 -04006 * Author: Pablo Neira Ayuso <pablo@gnumonks.org>
7 *
8 * All Rights Reserved
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 *
23 */
24
Pablo Neira Ayuso14506662014-02-20 18:43:15 +010025#include <stdio.h>
26#include <stdlib.h>
27#include <unistd.h>
28#include <string.h>
29#include <time.h>
Pablo Neira Ayuso50826a52016-05-10 18:00:51 +020030#include <netinet/in.h>
31#include <arpa/inet.h>
Pablo Neira Ayuso14506662014-02-20 18:43:15 +010032
33#include <libmnl/libmnl.h>
34#include <linux/if.h>
35#include <linux/if_link.h>
36#include <linux/rtnetlink.h>
37
Pablo Neira Ayusob9f6ffe2016-05-08 18:27:55 +020038#include <linux/gtp.h>
39#include <linux/if_link.h>
Pablo Neira Ayuso14506662014-02-20 18:43:15 +010040
Pablo Neira Ayuso448bce42016-05-08 21:43:40 +020041#include <libgtpnl/gtpnl.h>
42
Pablo Neira Ayuso14506662014-02-20 18:43:15 +010043int main(int argc, char *argv[])
44{
Pablo Neira Ayuso14506662014-02-20 18:43:15 +010045 char buf[MNL_SOCKET_BUFFER_SIZE];
Harald Welte3bf55c32017-03-15 18:03:42 +010046 int ret, sgsn_mode = 0;
Pablo Neira Ayuso14506662014-02-20 18:43:15 +010047
Harald Welte3bf55c32017-03-15 18:03:42 +010048 if (argc < 3) {
Oliver Smith6954da72022-09-07 15:48:16 +020049 printf("Usage: %s add <device> [--sgsn]\n", argv[0]);
50 printf(" %s del <device>\n", argv[0]);
Pablo Neira Ayuso14506662014-02-20 18:43:15 +010051 exit(EXIT_FAILURE);
52 }
53
Pablo Neira Ayuso448bce42016-05-08 21:43:40 +020054 if (!strcmp(argv[1], "del")) {
55 printf("destroying gtp interface...\n");
56 if (gtp_dev_destroy(argv[2]) < 0)
57 perror("gtp_dev_destroy");
58
59 return 0;
60 }
61
Harald Welte3bf55c32017-03-15 18:03:42 +010062 if (argc > 3 && !strcmp(argv[3], "--sgsn"))
63 sgsn_mode = 1;
64
Pablo Neira Ayuso7aa20872014-02-24 11:38:52 +010065 int fd1 = socket(AF_INET, SOCK_DGRAM, 0);
66 int fd2 = socket(AF_INET, SOCK_DGRAM, 0);
Pablo Neira Ayuso50826a52016-05-10 18:00:51 +020067 struct sockaddr_in sockaddr_fd1 = {
68 .sin_family = AF_INET,
69 .sin_port = htons(3386),
70 .sin_addr = {
71 .s_addr = INADDR_ANY,
72 },
73 };
74 struct sockaddr_in sockaddr_fd2 = {
75 .sin_family = AF_INET,
76 .sin_port = htons(2152),
77 .sin_addr = {
78 .s_addr = INADDR_ANY,
79 },
80 };
81
82 if (bind(fd1, (struct sockaddr *) &sockaddr_fd1,
83 sizeof(sockaddr_fd1)) < 0) {
84 perror("bind");
85 exit(EXIT_FAILURE);
86 }
87 if (bind(fd2, (struct sockaddr *) &sockaddr_fd2,
88 sizeof(sockaddr_fd2)) < 0) {
89 perror("bind");
90 exit(EXIT_FAILURE);
91 }
Pablo Neira Ayuso7aa20872014-02-24 11:38:52 +010092
Harald Welte3bf55c32017-03-15 18:03:42 +010093 if (sgsn_mode)
94 ret = gtp_dev_create_sgsn(-1, argv[2], fd1, fd2);
95 else
96 ret = gtp_dev_create(-1, argv[2], fd1, fd2);
Harald Weltea7a4df32017-03-15 20:53:08 +010097 if (ret < 0) {
98 perror("cannot create GTP device\n");
Pablo Neira Ayuso14506662014-02-20 18:43:15 +010099 exit(EXIT_FAILURE);
100 }
101
Pablo Neira Ayuso448bce42016-05-08 21:43:40 +0200102 fprintf(stderr, "WARNING: attaching dummy socket descriptors. Keep "
103 "this process running for testing purposes.\n");
Pablo Neira Ayuso50826a52016-05-10 18:00:51 +0200104
105 while (1) {
106 struct sockaddr_in addr;
107 socklen_t len = sizeof(addr);
108
109 ret = recvfrom(fd1, buf, sizeof(buf), 0,
110 (struct sockaddr *)&addr, &len);
111 printf("received %d bytes via UDP socket\n", ret);
112 }
Pablo Neira Ayuso448bce42016-05-08 21:43:40 +0200113
Pablo Neira Ayuso14506662014-02-20 18:43:15 +0100114 return 0;
115}