Project

General

Profile

Bug #6123 » 0005-IPv4-in-IPv6-GTP-and-IPv6-in-IPv4-GTP.patch

pablo, 10/06/2023 10:07 AM

View differences:

src/gtp-genl.c
53 53
	case AF_INET:
54 54
		if (t->ip.sgsn_addr.s_addr)
55 55
			mnl_attr_put_u32(nlh, GTPA_PEER_ADDRESS, t->ip.sgsn_addr.s_addr);
56
		else
57
			mnl_attr_put(nlh, GTPA_PEER_ADDR6, sizeof(t->ip6.sgsn_addr), &t->ip6.sgsn_addr);
58

  
56 59
		if (t->ip.ms_addr.s_addr)
57 60
			mnl_attr_put_u32(nlh, GTPA_MS_ADDRESS, t->ip.ms_addr.s_addr);
58 61
		break;
59 62
	case AF_INET6:
60
		mnl_attr_put(nlh, GTPA_PEER_ADDR6, sizeof(t->ip6.sgsn_addr), &t->ip6.sgsn_addr);
63
		if (t->ip.sgsn_addr.s_addr)
64
			mnl_attr_put_u32(nlh, GTPA_PEER_ADDRESS, t->ip.sgsn_addr.s_addr);
65
		else
66
			mnl_attr_put(nlh, GTPA_PEER_ADDR6, sizeof(t->ip6.sgsn_addr), &t->ip6.sgsn_addr);
67

  
61 68
		mnl_attr_put(nlh, GTPA_MS_ADDR6, sizeof(t->ip6.ms_addr), &t->ip6.ms_addr);
62 69
		break;
63 70
	}
......
126 133
			uint32_t o_tei;
127 134
		} v1;
128 135
	} u;
129
	union {
130
		struct {
131
			struct in_addr	sgsn_addr;
132
			struct in_addr	ms_addr;
133
		} ip;
134
		struct {
135
			struct in6_addr	sgsn_addr;
136
			struct in6_addr	ms_addr;
137
		} ip6;
138
	};
136
	struct {
137
		struct in_addr	sgsn_addr;
138
		struct in_addr	ms_addr;
139
	} ip;
140
	struct {
141
		struct in6_addr	sgsn_addr;
142
		struct in6_addr	ms_addr;
143
	} ip6;
139 144
};
140 145

  
141 146
static int genl_gtp_validate_cb(const struct nlattr *attr, void *data)
......
188 193
{
189 194
	struct nlattr *tb[GTPA_MAX + 1] = {};
190 195
	char buf[INET6_ADDRSTRLEN];
196
	int peer_family = AF_UNSPEC;
191 197
	struct gtp_pdp pdp = {};
192 198
	struct genlmsghdr *genl;
193 199

  
......
204 210
	if (tb[GTPA_O_TEI])
205 211
		pdp.u.v1.o_tei = mnl_attr_get_u32(tb[GTPA_O_TEI]);
206 212

  
213
	if (tb[GTPA_PEER_ADDRESS]) {
214
		pdp.ip.sgsn_addr.s_addr =
215
			mnl_attr_get_u32(tb[GTPA_PEER_ADDRESS]);
216
		peer_family = AF_INET;
217
	} else if (tb[GTPA_PEER_ADDR6]) {
218
		memcpy(&pdp.ip6.sgsn_addr, mnl_attr_get_payload(tb[GTPA_PEER_ADDR6]),
219
		       sizeof(struct in6_addr));
220
		peer_family = AF_INET6;
221
	}
222

  
207 223
	switch (pdp.family) {
208 224
	case AF_INET:
209
		if (tb[GTPA_PEER_ADDRESS]) {
210
			pdp.ip.sgsn_addr.s_addr =
211
				mnl_attr_get_u32(tb[GTPA_PEER_ADDRESS]);
212
		}
213 225
		if (tb[GTPA_MS_ADDRESS]) {
214 226
			pdp.ip.ms_addr.s_addr = mnl_attr_get_u32(tb[GTPA_MS_ADDRESS]);
215 227
		}
216 228
		break;
217 229
	case AF_INET6:
218
		if (tb[GTPA_PEER_ADDR6])
219
			memcpy(&pdp.ip6.sgsn_addr, mnl_attr_get_payload(tb[GTPA_PEER_ADDR6]), sizeof(struct in6_addr));
220 230
		if (tb[GTPA_MS_ADDR6])
221 231
			memcpy(&pdp.ip6.ms_addr, mnl_attr_get_payload(tb[GTPA_MS_ADDR6]), sizeof(struct in6_addr));
222 232
		break;
......
231 241
	else if (pdp.version == GTP_V1)
232 242
		printf("tei %u/%u ", pdp.u.v1.i_tei, pdp.u.v1.o_tei);
233 243

  
234
	printf("family %s ", pdp.family == AF_INET6 ? "ip6" : "ip");
244
	printf("%s ", pdp.family == AF_INET6 ? "ip6" : "ip");
235 245

  
236 246
	switch (pdp.family) {
237 247
	case AF_INET:
238 248
		inet_ntop(AF_INET, &pdp.ip.ms_addr, buf, sizeof(buf));
239 249
		printf("ms_addr %s ", buf);
240
		inet_ntop(AF_INET, &pdp.ip.sgsn_addr, buf, sizeof(buf));
241
		printf("sgsn_addr %s\n", buf);
242 250
		break;
243 251
	case AF_INET6:
244 252
		inet_ntop(AF_INET6, &pdp.ip6.ms_addr, buf, sizeof(buf));
245 253
		printf("ms_addr6 %s ", buf);
254
		break;
255
	}
256

  
257
	printf("%s ", peer_family == AF_INET6 ? "ip6" : "ip");
258

  
259
	switch (peer_family) {
260
	case AF_INET:
261
		inet_ntop(AF_INET, &pdp.ip.sgsn_addr, buf, sizeof(buf));
262
		printf("sgsn_addr %s\n", buf);
263
		break;
264
	case AF_INET6:
246 265
		inet_ntop(AF_INET6, &pdp.ip6.sgsn_addr, buf, sizeof(buf));
247 266
		printf("sgsn_addr6 %s\n", buf);
248 267
		break;
src/internal.h
16 16
	uint8_t		family;
17 17
	int             ifns;
18 18
	uint32_t	ifidx;
19
	union {
20
		struct {
21
			struct in_addr	ms_addr;
22
			struct in_addr	sgsn_addr;
23
		} ip;
24
		struct {
25
			struct in6_addr	ms_addr;
26
			struct in6_addr	sgsn_addr;
27
		} ip6;
28
	};
19
	struct {
20
		struct in_addr	ms_addr;
21
		struct in_addr	sgsn_addr;
22
	} ip;
23
	struct {
24
		struct in6_addr	ms_addr;
25
		struct in6_addr	sgsn_addr;
26
	} ip6;
29 27
	int		gtp_version;
30 28
	union {
31 29
		struct {
tools/gtp-tunnel.c
43 43

  
44 44
static void add_usage(const char *name)
45 45
{
46
	printf("%s add <gtp device> <v0> <tid> <family> <ms-addr> <sgsn-addr>\n",
46
	printf("%s add <gtp device> <v0> <tid> <family> <ms-addr> <family> <sgsn-addr>\n",
47 47
	       name);
48
	printf("%s add <gtp device> <v1> <i_tei> <o_tei> <family> <ms-addr> <sgsn-addr>\n",
48
	printf("%s add <gtp device> <v1> <i_tei> <o_tei> <family> <ms-addr> <family> <sgsn-addr>\n",
49 49
	       name);
50 50
}
51 51

  
......
60 60
		struct in_addr addr;
61 61
		struct in6_addr addr6;
62 62
	} sgsn;
63
	int optidx, family, peer_family;
63 64
	struct gtp_tunnel *t;
64 65
	uint32_t gtp_version;
65 66
	uint32_t gtp_ifidx;
66
	int optidx, family;
67 67

  
68
	if (argc < 8 || argc > 9) {
68
	if (argc < 9 || argc > 10) {
69 69
		add_usage(argv[0]);
70 70
		return EXIT_FAILURE;
71 71
	}
......
129 129
		break;
130 130
	}
131 131

  
132
	if (inet_pton(family, argv[optidx++], &sgsn) <= 0) {
132
	if (!strcmp(argv[optidx], "ip")) {
133
		peer_family = AF_INET;
134
	} else if (!strcmp(argv[optidx], "ip6")) {
135
		peer_family = AF_INET6;
136
	} else {
137
		fprintf(stderr, "wrong family `%s', expecting `ip' or `ip6'\n", argv[optidx]);
138
		return EXIT_FAILURE;
139
	}
140
	optidx++;
141

  
142
	if (inet_pton(peer_family, argv[optidx++], &sgsn) <= 0) {
133 143
		fprintf(stderr, "bad address for sgsn\n");
134 144
		exit(EXIT_FAILURE);
135 145
	}
136 146

  
137
	switch (family) {
147
	switch (peer_family) {
138 148
	case AF_INET:
139 149
		gtp_tunnel_set_sgsn_ip4(t, &sgsn.addr);
140 150
		break;
(7-7/7)
Add picture from clipboard (Maximum size: 48.8 MB)