Project

General

Profile

Bug #1952 » 0001-gtp-link-add-IPv6-support.patch

pablo, 11/15/2023 11:32 PM

View differences:

tools/gtp-link.c
40 40

  
41 41
#include <libgtpnl/gtpnl.h>
42 42

  
43
struct gtp_server_sock {
44
	int			family;
45
	int			fd1;
46
	int			fd2;
47
	socklen_t		len;
48
	struct {
49
		union {
50
			struct sockaddr_in	in;
51
			struct sockaddr_in6	in6;
52
		} fd1;
53
		union {
54
			struct sockaddr_in	in;
55
			struct sockaddr_in6	in6;
56
		} fd2;
57
	} sockaddr;
58
};
59

  
60
static void setup_sockaddr_in(struct sockaddr_in *sockaddr, uint16_t port)
61
{
62
	sockaddr->sin_family = AF_INET;
63
	sockaddr->sin_port = htons(port);
64
	sockaddr->sin_addr.s_addr = INADDR_ANY;
65
}
66

  
67
static void setup_sockaddr_in6(struct sockaddr_in6 *sockaddr, uint16_t port)
68
{
69
	sockaddr->sin6_family = AF_INET6;
70
	sockaddr->sin6_port = htons(port);
71
	sockaddr->sin6_addr = in6addr_any;
72
}
73

  
74
static int setup_socket(struct gtp_server_sock *gtp_sock, int family)
75
{
76
	int fd1 = socket(family, SOCK_DGRAM, 0);
77
	int fd2 = socket(family, SOCK_DGRAM, 0);
78

  
79
	if (fd1 < 0 || fd2 < 0)
80
		return -1;
81

  
82
	memset(gtp_sock, 0, sizeof(*gtp_sock));
83

  
84
	gtp_sock->family = family;
85
	gtp_sock->fd1 = fd1;
86
	gtp_sock->fd2 = fd2;
87

  
88
	switch (family) {
89
	case AF_INET:
90
		gtp_sock->len = sizeof(struct sockaddr_in);
91
		setup_sockaddr_in(&gtp_sock->sockaddr.fd1.in, 3386);
92
		setup_sockaddr_in(&gtp_sock->sockaddr.fd2.in, 2152);
93
		break;
94
	case AF_INET6:
95
		gtp_sock->len = sizeof(struct sockaddr_in6);
96
		setup_sockaddr_in6(&gtp_sock->sockaddr.fd1.in6, 3386);
97
		setup_sockaddr_in6(&gtp_sock->sockaddr.fd2.in6, 2152);
98
		break;
99
	}
100

  
101
	return 0;
102
}
103

  
43 104
int main(int argc, char *argv[])
44 105
{
45 106
	char buf[MNL_SOCKET_BUFFER_SIZE];
46
	int ret, sgsn_mode = 0;
107
	struct gtp_server_sock gtp_sock;
108
	int ret, sgsn_mode = 0, family;
47 109

  
48
	if (argc < 3) {
49
		printf("Usage: %s add <device> [--sgsn]\n", argv[0]);
110
	if (argc < 4) {
111
		printf("Usage: %s add <device> <family> [--sgsn]\n", argv[0]);
50 112
		printf("       %s del <device>\n", argv[0]);
51 113
		exit(EXIT_FAILURE);
52 114
	}
......
59 121
		return 0;
60 122
	}
61 123

  
62
	if (argc > 3 && !strcmp(argv[3], "--sgsn"))
124
	if (argc > 4 && !strcmp(argv[4], "--sgsn"))
63 125
		sgsn_mode = 1;
64 126

  
65
	int fd1 = socket(AF_INET, SOCK_DGRAM, 0);
66
	int fd2 = socket(AF_INET, SOCK_DGRAM, 0);
67
	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) {
127
	if (!strcmp(argv[3], "ip"))
128
		family = AF_INET;
129
	else if (!strcmp(argv[3], "ip6"))
130
		family = AF_INET6;
131
	else {
132
		fprintf(stderr, "unsupport family `%s', expecting `ip' or `ip6'\n",
133
			argv[3]);
134
		exit(EXIT_FAILURE);
135
	}
136

  
137
	if (setup_socket(&gtp_sock, family) < 0) {
138
		perror("socket");
139
		exit(EXIT_FAILURE);
140
	}
141

  
142
	if (bind(gtp_sock.fd1, (struct sockaddr *) &gtp_sock.sockaddr.fd1, gtp_sock.len) < 0) {
84 143
		perror("bind");
85 144
		exit(EXIT_FAILURE);
86 145
	}
87
	if (bind(fd2, (struct sockaddr *) &sockaddr_fd2,
88
		 sizeof(sockaddr_fd2)) < 0) {
146
	if (bind(gtp_sock.fd2, (struct sockaddr *) &gtp_sock.sockaddr.fd2, gtp_sock.len) < 0) {
89 147
		perror("bind");
90 148
		exit(EXIT_FAILURE);
91 149
	}
92 150

  
93 151
	if (sgsn_mode)
94
		ret = gtp_dev_create_sgsn(-1, argv[2], fd1, fd2);
152
		ret = gtp_dev_create_sgsn(-1, argv[2], gtp_sock.fd1, gtp_sock.fd2);
95 153
	else
96
		ret = gtp_dev_create(-1, argv[2], fd1, fd2);
154
		ret = gtp_dev_create(-1, argv[2], gtp_sock.fd1, gtp_sock.fd2);
97 155
	if (ret < 0) {
98 156
		perror("cannot create GTP device\n");
99 157
		exit(EXIT_FAILURE);
......
103 161
			"this process running for testing purposes.\n");
104 162

  
105 163
	while (1) {
106
		struct sockaddr_in addr;
107
		socklen_t len = sizeof(addr);
164
		union {
165
			struct sockaddr_in addr;
166
			struct sockaddr_in6 addr6;
167
		} sock;
108 168

  
109
		ret = recvfrom(fd1, buf, sizeof(buf), 0,
110
			       (struct sockaddr *)&addr, &len);
169
		ret = recvfrom(gtp_sock.fd1, buf, sizeof(buf), 0,
170
			       (struct sockaddr *)&sock, &gtp_sock.len);
111 171
		printf("received %d bytes via UDP socket\n", ret);
112 172
	}
113 173

  
(7-7/33)
Add picture from clipboard (Maximum size: 48.8 MB)