blob: e413d1175f30b240bec4005742b4f388d77fc30c [file] [log] [blame]
Pau Espin Pedrol641206a2021-05-03 17:24:30 +02001/*
Harald Welte632e8432017-09-05 18:12:14 +02002 * OsmoGGSN - Gateway GPRS Support Node
jjako52c24142002-12-16 13:33:51 +00003 * Copyright (C) 2002 Mondru AB.
Pau Espin Pedrol641206a2021-05-03 17:24:30 +02004 *
jjako52c24142002-12-16 13:33:51 +00005 * The contents of this file may be used under the terms of the GNU
6 * General Public License Version 2, provided that the above copyright
7 * notice and this permission notice is included in all copies or
8 * substantial portions of the software.
Pau Espin Pedrol641206a2021-05-03 17:24:30 +02009 *
jjako52c24142002-12-16 13:33:51 +000010 */
11
12/*
Pau Espin Pedrol641206a2021-05-03 17:24:30 +020013 * gtpie.c: Contains functions to encapsulate and decapsulate GTP
14 * information elements
jjako52c24142002-12-16 13:33:51 +000015 *
16 *
17 * Encapsulation
18 * - gtpie_tlv, gtpie_tv0, gtpie_tv1, gtpie_tv2 ... Adds information
19 * elements to a buffer.
20 *
21 * Decapsulation
22 * - gtpie_decaps: Returns array with pointers to information elements.
23 * - getie_getie: Returns the pointer of a particular element.
24 * - gtpie_gettlv: Copies tlv information element. Return 0 on success.
25 * - gtpie_gettv: Copies tv information element. Return 0 on success.
26 *
27 */
28
jjako0fe0df02004-09-17 11:30:40 +000029#include <../config.h>
30
31#ifdef HAVE_STDINT_H
32#include <stdint.h>
33#endif
34
jjako52c24142002-12-16 13:33:51 +000035#include <stdio.h>
36#include <sys/types.h>
37#include <netinet/in.h>
38#include <string.h>
39
40#include "gtpie.h"
41
Harald Weltec5150ce2017-10-13 06:35:46 +020042/*! Encode a TLV type Information Element.
43 * \param[inout] p Pointer to output packet to which IE is appended
44 * \param[inout] length Up to which byte length is \a p used/filled
45 * \param[in] size Total size of \a p in bytes
46 * \param[in] t Tag / Information Element Identifier
47 * \param[in] l Length of value \a v in bytes
48 * \param[in] v Pointer to input value
49 * \returns 0 on success, 1 on error */
Harald Weltebed35df2011-11-02 13:06:18 +010050int gtpie_tlv(void *p, unsigned int *length, unsigned int size, uint8_t t,
Harald Welte02af9b32017-10-13 05:04:33 +020051 int l, const void *v)
Harald Weltebed35df2011-11-02 13:06:18 +010052{
53 if ((*length + 3 + l) >= size)
54 return 1;
55 ((union gtpie_member *)(p + *length))->tlv.t = hton8(t);
56 ((union gtpie_member *)(p + *length))->tlv.l = hton16(l);
57 memcpy((void *)(p + *length + 3), v, l);
58 *length += 3 + l;
59 return 0;
jjako52c24142002-12-16 13:33:51 +000060}
61
Harald Weltec5150ce2017-10-13 06:35:46 +020062/*! Encode a TV0 (Tag + value) type Information Element.
63 * \param[inout] p Pointer to output packet to which IE is appended
64 * \param[inout] length Up to which byte length is \a p used/filled
65 * \param[in] size Total size of \a p in bytes
66 * \param[in] t Tag / Information Element Identifier
67 * \param[in] l Length of value \a v in bytes
68 * \param[in] v Pointer to input value
69 * \returns 0 on success, 1 on error */
Harald Weltebed35df2011-11-02 13:06:18 +010070int gtpie_tv0(void *p, unsigned int *length, unsigned int size, uint8_t t,
Harald Welte02af9b32017-10-13 05:04:33 +020071 int l, const uint8_t * v)
Harald Weltebed35df2011-11-02 13:06:18 +010072{
73 if ((*length + 1 + l) >= size)
74 return 1;
75 ((union gtpie_member *)(p + *length))->tv0.t = hton8(t);
76 memcpy((void *)(p + *length + 1), v, l);
77 *length += 1 + l;
78 return 0;
jjako52c24142002-12-16 13:33:51 +000079}
80
Harald Weltec5150ce2017-10-13 06:35:46 +020081/*! Encode a TV1 (Tag + 8bit value) type Information Element.
82 * \param[inout] p Pointer to output packet to which IE is appended
83 * \param[inout] length Up to which byte length is \a p used/filled
84 * \param[in] size Total size of \a p in bytes
85 * \param[in] t Tag / Information Element Identifier
86 * \param[in] v Input value
87 * \returns 0 on success, 1 on error */
Harald Weltebed35df2011-11-02 13:06:18 +010088int gtpie_tv1(void *p, unsigned int *length, unsigned int size, uint8_t t,
89 uint8_t v)
90{
91 if ((*length + 2) >= size)
92 return 1;
93 ((union gtpie_member *)(p + *length))->tv1.t = hton8(t);
94 ((union gtpie_member *)(p + *length))->tv1.v = hton8(v);
95 *length += 2;
96 return 0;
jjako52c24142002-12-16 13:33:51 +000097}
98
Harald Weltec5150ce2017-10-13 06:35:46 +020099/*! Encode a TV2 (Tag + 16bit value) type Information Element.
100 * \param[inout] p Pointer to output packet to which IE is appended
101 * \param[inout] length Up to which byte length is \a p used/filled
102 * \param[in] size Total size of \a p in bytes
103 * \param[in] t Tag / Information Element Identifier
104 * \param[in] v Input value
105 * \returns 0 on success, 1 on error */
Harald Weltebed35df2011-11-02 13:06:18 +0100106int gtpie_tv2(void *p, unsigned int *length, unsigned int size, uint8_t t,
107 uint16_t v)
108{
109 if ((*length + 3) >= size)
110 return 1;
111 ((union gtpie_member *)(p + *length))->tv2.t = hton8(t);
112 ((union gtpie_member *)(p + *length))->tv2.v = hton16(v);
113 *length += 3;
114 return 0;
jjako52c24142002-12-16 13:33:51 +0000115}
116
Harald Weltec5150ce2017-10-13 06:35:46 +0200117/*! Encode a TV4 (Tag + 32bit value) type Information Element.
118 * \param[inout] p Pointer to output packet to which IE is appended
119 * \param[inout] length Up to which byte length is \a p used/filled
120 * \param[in] size Total size of \a p in bytes
121 * \param[in] t Tag / Information Element Identifier
122 * \param[in] v Input value
123 * \returns 0 on success, 1 on error */
Harald Weltebed35df2011-11-02 13:06:18 +0100124int gtpie_tv4(void *p, unsigned int *length, unsigned int size, uint8_t t,
125 uint32_t v)
126{
127 if ((*length + 5) >= size)
128 return 1;
129 ((union gtpie_member *)(p + *length))->tv4.t = hton8(t);
130 ((union gtpie_member *)(p + *length))->tv4.v = hton32(v);
131 *length += 5;
132 return 0;
jjako52c24142002-12-16 13:33:51 +0000133}
134
Harald Weltec5150ce2017-10-13 06:35:46 +0200135/*! Encode a TV8 (Tag + 64bit value) type Information Element.
136 * \param[inout] p Pointer to output packet to which IE is appended
137 * \param[inout] length Up to which byte length is \a p used/filled
138 * \param[in] size Total size of \a p in bytes
139 * \param[in] t Tag / Information Element Identifier
140 * \param[in] v Input value
141 * \returns 0 on success, 1 on error */
Harald Weltebed35df2011-11-02 13:06:18 +0100142int gtpie_tv8(void *p, unsigned int *length, unsigned int size, uint8_t t,
143 uint64_t v)
144{
145 if ((*length + 9) >= size)
146 return 1;
147 ((union gtpie_member *)(p + *length))->tv8.t = hton8(t);
148 ((union gtpie_member *)(p + *length))->tv8.v = hton64(v);
149 *length += 9;
150 return 0;
jjako08d331d2003-10-13 20:33:30 +0000151}
152
Harald Weltec5150ce2017-10-13 06:35:46 +0200153/*! Obtain a GTP IE for a given tag/IEI from a list/array.
154 * \param[in] ie Array of GTPIE
155 * \param[in] type Tag/IEI for which we're looking
156 * \param[in] instance Instance (number of occurence) of this IEI
157 * \returns index into \a ie on success; -1 if not found */
Harald Weltebed35df2011-11-02 13:06:18 +0100158int gtpie_getie(union gtpie_member *ie[], int type, int instance)
159{
160 int j;
161 for (j = 0; j < GTPIE_SIZE; j++) {
162 if ((ie[j] != 0) && (ie[j]->t == type)) {
163 if (instance-- == 0)
164 return j;
165 }
jjako08d331d2003-10-13 20:33:30 +0000166 }
Harald Weltebed35df2011-11-02 13:06:18 +0100167 return -1;
jjako52c24142002-12-16 13:33:51 +0000168}
169
Harald Weltec5150ce2017-10-13 06:35:46 +0200170/*! Determine if IE for a given tag/IEI exists in a list/array.
171 * \param[in] ie Array of GTPIE
172 * \param[in] type Tag/IEI for which we're looking
173 * \param[in] instance Instance (number of occurence) of this IEI
174 * \returns 1 if IEI instance present in \a ie; 0 if not */
Harald Weltebed35df2011-11-02 13:06:18 +0100175int gtpie_exist(union gtpie_member *ie[], int type, int instance)
176{
177 int j;
178 for (j = 0; j < GTPIE_SIZE; j++) {
179 if ((ie[j] != 0) && (ie[j]->t == type)) {
180 if (instance-- == 0)
181 return 1;
182 }
183 }
184 return 0;
185}
jjako52c24142002-12-16 13:33:51 +0000186
Harald Weltec5150ce2017-10-13 06:35:46 +0200187/*! Obtain Value of TLV-type IE for a given tag/IEI from a list/array.
188 * \param[in] ie Array of GTPIE
189 * \param[in] type Tag/IEI for which we're looking
190 * \param[in] instance Instance (number of occurence) of this IEI
191 * \param[out] length Length of IE
192 * \param[inout] dst Caller-allocated buffer where to store value
193 * \param[in] size Size of \a dst in bytes
194 * \returns 0 on sucess; EOF in case value is larger than \a size */
Harald Weltebed35df2011-11-02 13:06:18 +0100195int gtpie_gettlv(union gtpie_member *ie[], int type, int instance,
196 unsigned int *length, void *dst, unsigned int size)
197{
198 int ien;
199 ien = gtpie_getie(ie, type, instance);
200 if (ien >= 0) {
201 *length = ntoh16(ie[ien]->tlv.l);
202 if (*length <= size)
203 memcpy(dst, ie[ien]->tlv.v, *length);
204 else
205 return EOF;
206 }
207 return 0;
208}
209
Harald Weltec5150ce2017-10-13 06:35:46 +0200210/*! Obtain Value of TV0-type IE for a given tag/IEI from a list/array.
211 * \param[in] ie Array of GTPIE
212 * \param[in] type Tag/IEI for which we're looking
213 * \param[in] instance Instance (number of occurence) of this IEI
214 * \param[inout] dst Caller-allocated buffer where to store value
215 * \param[in] size Size of value in bytes
216 * \returns 0 on sucess; EOF in case IE not found */
Harald Weltebed35df2011-11-02 13:06:18 +0100217int gtpie_gettv0(union gtpie_member *ie[], int type, int instance,
218 void *dst, unsigned int size)
219{
220 int ien;
221 ien = gtpie_getie(ie, type, instance);
222 if (ien >= 0)
223 memcpy(dst, ie[ien]->tv0.v, size);
224 else
225 return EOF;
226 return 0;
227}
228
Harald Weltec5150ce2017-10-13 06:35:46 +0200229/*! Obtain Value of TV1-type IE for a given tag/IEI from a list/array.
230 * \param[in] ie Array of GTPIE
231 * \param[in] type Tag/IEI for which we're looking
232 * \param[in] instance Instance (number of occurence) of this IEI
233 * \param[inout] dst Caller-allocated buffer where to store value
234 * \returns 0 on sucess; EOF in case IE not found */
Harald Weltebed35df2011-11-02 13:06:18 +0100235int gtpie_gettv1(union gtpie_member *ie[], int type, int instance,
236 uint8_t * dst)
237{
238 int ien;
239 ien = gtpie_getie(ie, type, instance);
240 if (ien >= 0)
241 *dst = ntoh8(ie[ien]->tv1.v);
242 else
243 return EOF;
244 return 0;
245}
246
Harald Weltec5150ce2017-10-13 06:35:46 +0200247/*! Obtain Value of TV2-type IE for a given tag/IEI from a list/array.
248 * \param[in] ie Array of GTPIE
249 * \param[in] type Tag/IEI for which we're looking
250 * \param[in] instance Instance (number of occurence) of this IEI
251 * \param[inout] dst Caller-allocated buffer where to store value
252 * \returns 0 on sucess; EOF in case IE not found */
Harald Weltebed35df2011-11-02 13:06:18 +0100253int gtpie_gettv2(union gtpie_member *ie[], int type, int instance,
254 uint16_t * dst)
255{
256 int ien;
257 ien = gtpie_getie(ie, type, instance);
258 if (ien >= 0)
259 *dst = ntoh16(ie[ien]->tv2.v);
260 else
261 return EOF;
262 return 0;
263}
264
Harald Weltec5150ce2017-10-13 06:35:46 +0200265/*! Obtain Value of TV4-type IE for a given tag/IEI from a list/array.
266 * \param[in] ie Array of GTPIE
267 * \param[in] type Tag/IEI for which we're looking
268 * \param[in] instance Instance (number of occurence) of this IEI
269 * \param[inout] dst Caller-allocated buffer where to store value
270 * \returns 0 on sucess; EOF in case IE not found */
Harald Weltebed35df2011-11-02 13:06:18 +0100271int gtpie_gettv4(union gtpie_member *ie[], int type, int instance,
272 uint32_t * dst)
273{
274 int ien;
275 ien = gtpie_getie(ie, type, instance);
276 if (ien >= 0)
277 *dst = ntoh32(ie[ien]->tv4.v);
278 else
279 return EOF;
280 return 0;
281}
282
Harald Weltec5150ce2017-10-13 06:35:46 +0200283/*! Obtain Value of TV8-type IE for a given tag/IEI from a list/array.
284 * \param[in] ie Array of GTPIE
285 * \param[in] type Tag/IEI for which we're looking
286 * \param[in] instance Instance (number of occurence) of this IEI
287 * \param[inout] dst Caller-allocated buffer where to store value
288 * \returns 0 on sucess; EOF in case IE not found */
Harald Weltebed35df2011-11-02 13:06:18 +0100289int gtpie_gettv8(union gtpie_member *ie[], int type, int instance,
290 uint64_t * dst)
291{
292 int ien;
293 ien = gtpie_getie(ie, type, instance);
294 if (ien >= 0)
295 *dst = ntoh64(ie[ien]->tv8.v);
296 else
297 return EOF;
298 return 0;
299}
300
Harald Weltec5150ce2017-10-13 06:35:46 +0200301/*! Parse an incoming GTP packet into its Information Elements.
302 * \param[out] ie Caller-allocated Array of GTPIE
303 * \param[in] version GTP protocol version
304 * \param[in] pack Pointer to raw GTP packet (payload part)
305 * \param[in] len Length of \a pack in bytes
306 * \returns 0 on sucess; EOF in case IE not found */
Harald Weltea9640272017-10-13 12:06:08 +0200307int gtpie_decaps(union gtpie_member *ie[], int version, const void *pack,
Harald Weltebed35df2011-11-02 13:06:18 +0100308 unsigned len)
309{
310 int i;
311 int j = 0;
Harald Weltea9640272017-10-13 12:06:08 +0200312 const unsigned char *p;
313 const unsigned char *end;
Harald Weltebed35df2011-11-02 13:06:18 +0100314
315 end = (unsigned char *)pack + len;
316 p = pack;
317
318 memset(ie, 0, sizeof(union gtpie_member *) * GTPIE_SIZE);
319
320 while ((p < end) && (j < GTPIE_SIZE)) {
321 if (GTPIE_DEBUG) {
322 printf("The packet looks like this:\n");
323 for (i = 0; i < (end - p); i++) {
324 printf("%02x ",
325 (unsigned char)*(char *)(p + i));
326 if (!((i + 1) % 16))
327 printf("\n");
328 };
329 printf("\n");
330 }
331
332 switch (*p) {
333 case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
334 case GTPIE_REORDER:
335 case GTPIE_MAP_CAUSE:
336 case GTPIE_MS_VALIDATED:
337 case GTPIE_RECOVERY:
338 case GTPIE_SELECTION_MODE:
339 case GTPIE_TEARDOWN:
340 case GTPIE_NSAPI:
341 case GTPIE_RANAP_CAUSE:
342 case GTPIE_RP_SMS:
343 case GTPIE_RP:
344 case GTPIE_MS_NOT_REACH:
BJovke03dbafb2016-09-15 13:41:41 +0200345 case GTPIE_BCM:
Harald Weltebed35df2011-11-02 13:06:18 +0100346 if (j < GTPIE_SIZE) {
347 ie[j] = (union gtpie_member *)p;
348 if (GTPIE_DEBUG)
349 printf
350 ("GTPIE TV1 found. Type %d, value %d\n",
351 ie[j]->tv1.t, ie[j]->tv1.v);
352 p += 1 + 1;
353 j++;
354 }
355 break;
356 case GTPIE_FL_DI: /* TV GTPIE types with value length 2 or 4 */
357 case GTPIE_FL_C:
358 if (version != 0) {
359 if (j < GTPIE_SIZE) { /* GTPIE_TEI_DI & GTPIE_TEI_C with length 4 */
360 /* case GTPIE_TEI_DI: gtp1 */
361 /* case GTPIE_TEI_C: gtp1 */
362 ie[j] = (union gtpie_member *)p;
363 if (GTPIE_DEBUG)
364 printf
365 ("GTPIE TV 4 found. Type %d, value %d\n",
366 ie[j]->tv4.t,
367 ie[j]->tv4.v);
368 p += 1 + 4;
369 j++;
370 }
371 break;
372 }
373 case GTPIE_PFI: /* TV GTPIE types with value length 2 */
374 case GTPIE_CHARGING_C:
375 case GTPIE_TRACE_REF:
376 case GTPIE_TRACE_TYPE:
377 if (j < GTPIE_SIZE) {
378 ie[j] = (union gtpie_member *)p;
379 if (GTPIE_DEBUG)
380 printf
381 ("GTPIE TV2 found. Type %d, value %d\n",
382 ie[j]->tv2.t, ie[j]->tv2.v);
383 p += 1 + 2;
384 j++;
385 }
386 break;
387 case GTPIE_QOS_PROFILE0: /* TV GTPIE types with value length 3 */
388 case GTPIE_P_TMSI_S:
389 if (j < GTPIE_SIZE) {
390 ie[j] = (union gtpie_member *)p;
391 if (GTPIE_DEBUG)
392 printf
393 ("GTPIE TV 3 found. Type %d, value %d, %d, %d\n",
394 ie[j]->tv0.t, ie[j]->tv0.v[0],
395 ie[j]->tv0.v[1], ie[j]->tv0.v[2]);
396 p += 1 + 3;
397 j++;
398 }
399 break;
400 case GTPIE_TLLI: /* TV GTPIE types with value length 4 */
401 case GTPIE_P_TMSI:
402 case GTPIE_CHARGING_ID:
403 /* case GTPIE_TEI_DI: Handled by GTPIE_FL_DI */
404 /* case GTPIE_TEI_C: Handled by GTPIE_FL_DI */
405 if (j < GTPIE_SIZE) {
406 ie[j] = (union gtpie_member *)p;
407 if (GTPIE_DEBUG)
408 printf
409 ("GTPIE TV 4 found. Type %d, value %d\n",
410 ie[j]->tv4.t, ie[j]->tv4.v);
411 p += 1 + 4;
412 j++;
413 }
414 break;
415 case GTPIE_TEI_DII: /* TV GTPIE types with value length 5 */
416 if (j < GTPIE_SIZE) {
417 ie[j] = (union gtpie_member *)p;
418 if (GTPIE_DEBUG)
419 printf("GTPIE TV 5 found. Type %d\n",
420 ie[j]->tv0.t);
421 p += 1 + 5;
422 j++;
423 }
424 break;
425 case GTPIE_RAB_CONTEXT: /* TV GTPIE types with value length 7 */
426 if (j < GTPIE_SIZE) {
427 ie[j] = (union gtpie_member *)p;
428 if (GTPIE_DEBUG)
429 printf("GTPIE TV 7 found. Type %d\n",
430 ie[j]->tv0.t);
431 p += 1 + 7;
432 j++;
433 }
434 break;
435 case GTPIE_IMSI: /* TV GTPIE types with value length 8 */
436 if (j < GTPIE_SIZE) {
437 ie[j] = (union gtpie_member *)p;
438 if (GTPIE_DEBUG)
439 printf
440 ("GTPIE_IMSI - GTPIE TV 8 found. Type %d, value 0x%llx\n",
441 ie[j]->tv0.t, ie[j]->tv8.v);
442 p += 1 + 8;
443 j++;
444 }
445 break;
446 case GTPIE_RAI: /* TV GTPIE types with value length 6 */
447 if (j < GTPIE_SIZE) {
448 ie[j] = (union gtpie_member *)p;
449 if (GTPIE_DEBUG)
450 printf
451 ("GTPIE_RAI - GTPIE TV 6 found. Type %d, value 0x%llx\n",
452 ie[j]->tv0.t, ie[j]->tv8.v);
453 p += 1 + 6;
454 j++;
455 }
456 break;
457 case GTPIE_AUTH_TRIPLET: /* TV GTPIE types with value length 28 */
458 if (j < GTPIE_SIZE) {
459 ie[j] = (union gtpie_member *)p;
460 if (GTPIE_DEBUG)
461 printf("GTPIE TV 28 found. Type %d\n",
462 ie[j]->tv0.t);
463 p += 1 + 28;
464 j++;
465 }
466 break;
467 case GTPIE_EXT_HEADER_T: /* GTP extension header */
468 if (j < GTPIE_SIZE) {
469 ie[j] = (union gtpie_member *)p;
470 if (GTPIE_DEBUG)
471 printf
472 ("GTPIE GTP extension header found. Type %d\n",
473 ie[j]->ext.t);
474 p += 2 + ntoh8(ie[j]->ext.l);
475 j++;
476 }
477 break;
478 case GTPIE_EUA: /* TLV GTPIE types with variable length */
479 case GTPIE_MM_CONTEXT:
480 case GTPIE_PDP_CONTEXT:
481 case GTPIE_APN:
482 case GTPIE_PCO:
483 case GTPIE_GSN_ADDR:
484 case GTPIE_MSISDN:
485 case GTPIE_QOS_PROFILE:
486 case GTPIE_AUTH_QUINTUP:
487 case GTPIE_TFT:
488 case GTPIE_TARGET_INF:
489 case GTPIE_UTRAN_TRANS:
490 case GTPIE_RAB_SETUP:
491 case GTPIE_TRIGGER_ID:
492 case GTPIE_OMC_ID:
Harald Weltebc41c8d2017-10-09 10:15:04 +0800493 case GTPIE_RAN_T_CONTAIN:
494 case GTPIE_PDP_CTX_PRIO:
495 case GTPIE_ADDL_RAB_S_I:
496 case GTPIE_SGSN_NUMBER:
Harald Welte89e1abc2017-10-08 07:50:20 +0800497 case GTPIE_COMMON_FLAGS:
Harald Weltebc41c8d2017-10-09 10:15:04 +0800498 case GTPIE_APN_RESTR:
499 case GTPIE_R_PRIO_LCS:
Harald Weltebed35df2011-11-02 13:06:18 +0100500 case GTPIE_RAT_TYPE:
501 case GTPIE_USER_LOC:
502 case GTPIE_MS_TZ:
503 case GTPIE_IMEI_SV:
Harald Weltebc41c8d2017-10-09 10:15:04 +0800504 case GTPIE_CML_CHG_I_CT:
505 case GTPIE_MBMS_UE_CTX:
506 case GTPIE_TMGI:
507 case GTPIE_RIM_ROUT_ADDR:
508 case GTPIE_MBMS_PCO:
509 case GTPIE_MBMS_SA:
510 case GTPIE_SRNC_PDCP_CTX:
511 case GTPIE_ADDL_TRACE:
512 case GTPIE_HOP_CTR:
513 case GTPIE_SEL_PLMN_ID:
514 case GTPIE_MBMS_SESS_ID:
515 case GTPIE_MBMS_2_3G_IND:
516 case GTPIE_ENH_NSAPI:
517 case GTPIE_MBMS_SESS_DUR:
518 case GTPIE_A_MBMS_TRAC_I:
519 case GTPIE_MBMS_S_REP_N:
520 case GTPIE_MBMS_TTDT:
521 case GTPIE_PS_HO_REQ_CTX:
522 case GTPIE_BSS_CONTAINER:
523 case GTPIE_CELL_ID:
524 case GTPIE_PDU_NUMBERS:
525 case GTPIE_BSSGP_CAUSE:
526 case GTPIE_RQD_MBMS_BCAP:
527 case GTPIE_RIM_RA_DISCR:
528 case GTPIE_L_SETUP_PFCS:
529 case GTPIE_PS_HO_XID_PAR:
530 case GTPIE_MS_CHG_REP_A:
531 case GTPIE_DIR_TUN_FLAGS:
532 case GTPIE_CORREL_ID:
533 case GTPIE_MBMS_FLOWI:
534 case GTPIE_MBMS_MC_DIST:
535 case GTPIE_MBMS_DIST_ACK:
536 case GTPIE_R_IRAT_HO_INF:
537 case GTPIE_RFSP_IDX:
538 case GTPIE_FQDN:
539 case GTPIE_E_ALL_PRIO_1:
540 case GTPIE_E_ALL_PRIO_2:
541 case GTPIE_E_CMN_FLAGS:
542 case GTPIE_U_CSG_INFO:
543 case GTPIE_CSG_I_REP_ACT:
544 case GTPIE_CSG_ID:
545 case GTPIE_CSG_MEMB_IND:
546 case GTPIE_AMBR:
547 case GTPIE_UE_NET_CAPA:
548 case GTPIE_UE_AMBR:
549 case GTPIE_APN_AMBR_NS:
550 case GTPIE_GGSN_BACKOFF:
551 case GTPIE_S_PRIO_IND:
552 case GTPIE_S_PRIO_IND_NS:
553 case GTPIE_H_BR_16MBPS_F:
554 case GTPIE_A_MMCTX_SRVCC:
555 case GTPIE_A_FLAGS_SRVCC:
556 case GTPIE_STN_SR:
557 case GTPIE_C_MSISDN:
558 case GTPIE_E_RANAP_CAUSE:
559 case GTPIE_ENODEB_ID:
560 case GTPIE_SEL_MODE_NS:
561 case GTPIE_ULI_TIMESTAMP:
562 case GTPIE_CHARGING_ADDR:
Harald Weltebed35df2011-11-02 13:06:18 +0100563 case GTPIE_PRIVATE:
564 if (j < GTPIE_SIZE) {
565 ie[j] = (union gtpie_member *)p;
566 if (GTPIE_DEBUG)
567 printf("GTPIE TLV found. Type %d\n",
568 ie[j]->tlv.t);
569 p += 3 + ntoh16(ie[j]->tlv.l);
570 j++;
571 }
572 break;
573 default:
574 if (GTPIE_DEBUG)
575 printf("GTPIE something unknown. Type %d\n",
576 *p);
577 return EOF; /* We received something unknown */
578 }
579 }
580 if (p == end) {
581 if (GTPIE_DEBUG)
582 printf("GTPIE normal return. %lx %lx\n",
583 (unsigned long)p, (unsigned long)end);
584 return 0; /* We landed at the end of the packet: OK */
585 } else if (!(j < GTPIE_SIZE)) {
586 if (GTPIE_DEBUG)
587 printf("GTPIE too many elements.\n");
588 return EOF; /* We received too many information elements */
589 } else {
590 if (GTPIE_DEBUG)
591 printf("GTPIE exceeded end of packet. %lx %lx\n",
592 (unsigned long)p, (unsigned long)end);
593 return EOF; /* We exceeded the end of the packet: Error */
594 }
595}
596
Harald Weltec5150ce2017-10-13 06:35:46 +0200597/*! Encode GTP packet payload from Array of Information Elements.
598 * \param[out] ie Input Array of GTPIE
599 * \param[out] pack Pointer to caller-allocated buffer for raw GTP packet (GTPIE_MAX length)
600 * \param[out] len Encoded length of \a pack in bytes
601 * \returns 0 on sucess; 2 for out-of-space */
Harald Weltebed35df2011-11-02 13:06:18 +0100602int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len)
603{
604 int i;
605 unsigned char *p;
606 unsigned char *end;
Harald Weltebed35df2011-11-02 13:06:18 +0100607 int iesize;
608
609 p = pack;
610
611 memset(pack, 0, GTPIE_MAX);
612 end = p + GTPIE_MAX;
613 for (i = 1; i < GTPIE_SIZE; i++)
614 if (ie[i] != 0) {
615 if (GTPIE_DEBUG)
616 printf("gtpie_encaps. Type %d\n", i);
Harald Weltebed35df2011-11-02 13:06:18 +0100617 switch (i) {
618 case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
619 case GTPIE_REORDER:
620 case GTPIE_MAP_CAUSE:
621 case GTPIE_MS_VALIDATED:
622 case GTPIE_RECOVERY:
623 case GTPIE_SELECTION_MODE:
624 case GTPIE_TEARDOWN:
625 case GTPIE_NSAPI:
626 case GTPIE_RANAP_CAUSE:
627 case GTPIE_RP_SMS:
628 case GTPIE_RP:
629 case GTPIE_MS_NOT_REACH:
BJovke03dbafb2016-09-15 13:41:41 +0200630 case GTPIE_BCM:
Harald Weltebed35df2011-11-02 13:06:18 +0100631 iesize = 2;
632 break;
633 case GTPIE_FL_DI: /* TV GTPIE types with value length 2 */
634 case GTPIE_FL_C:
635 case GTPIE_PFI:
636 case GTPIE_CHARGING_C:
637 case GTPIE_TRACE_REF:
638 case GTPIE_TRACE_TYPE:
639 iesize = 3;
640 break;
641 case GTPIE_QOS_PROFILE0: /* TV GTPIE types with value length 3 */
642 case GTPIE_P_TMSI_S:
643 iesize = 4;
644 break;
645 case GTPIE_TLLI: /* TV GTPIE types with value length 4 */
646 case GTPIE_P_TMSI:
647 /* case GTPIE_TEI_DI: only in gtp1 */
648 /* case GTPIE_TEI_C: only in gtp1 */
649 case GTPIE_CHARGING_ID:
650 iesize = 5;
651 break;
652 case GTPIE_TEI_DII: /* TV GTPIE types with value length 5 */
653 iesize = 6;
654 break;
Harald Weltef6c5f952017-10-14 07:56:41 +0200655 case GTPIE_RAI: /* TV GTPIE types with value length 6 */
656 iesize = 7;
657 break;
Harald Weltebed35df2011-11-02 13:06:18 +0100658 case GTPIE_RAB_CONTEXT: /* TV GTPIE types with value length 7 */
659 iesize = 8;
660 break;
661 case GTPIE_IMSI: /* TV GTPIE types with value length 8 */
Harald Weltebed35df2011-11-02 13:06:18 +0100662 iesize = 9;
663 break;
664 case GTPIE_AUTH_TRIPLET: /* TV GTPIE types with value length 28 */
665 iesize = 29;
666 break;
667 case GTPIE_EXT_HEADER_T: /* GTP extension header */
668 iesize = 2 + hton8(ie[i]->ext.l);
669 break;
670 case GTPIE_EUA: /* TLV GTPIE types with length length 2 */
671 case GTPIE_MM_CONTEXT:
672 case GTPIE_PDP_CONTEXT:
673 case GTPIE_APN:
674 case GTPIE_PCO:
675 case GTPIE_GSN_ADDR:
676 case GTPIE_MSISDN:
677 case GTPIE_QOS_PROFILE:
678 case GTPIE_AUTH_QUINTUP:
679 case GTPIE_TFT:
680 case GTPIE_TARGET_INF:
681 case GTPIE_UTRAN_TRANS:
682 case GTPIE_RAB_SETUP:
683 case GTPIE_TRIGGER_ID:
684 case GTPIE_OMC_ID:
Harald Weltebc41c8d2017-10-09 10:15:04 +0800685 case GTPIE_RAN_T_CONTAIN:
686 case GTPIE_PDP_CTX_PRIO:
687 case GTPIE_ADDL_RAB_S_I:
688 case GTPIE_SGSN_NUMBER:
Harald Welte89e1abc2017-10-08 07:50:20 +0800689 case GTPIE_COMMON_FLAGS:
Harald Weltebc41c8d2017-10-09 10:15:04 +0800690 case GTPIE_APN_RESTR:
691 case GTPIE_R_PRIO_LCS:
692 case GTPIE_RAT_TYPE:
693 case GTPIE_USER_LOC:
694 case GTPIE_MS_TZ:
695 case GTPIE_IMEI_SV:
696 case GTPIE_CML_CHG_I_CT:
697 case GTPIE_MBMS_UE_CTX:
698 case GTPIE_TMGI:
699 case GTPIE_RIM_ROUT_ADDR:
700 case GTPIE_MBMS_PCO:
701 case GTPIE_MBMS_SA:
702 case GTPIE_SRNC_PDCP_CTX:
703 case GTPIE_ADDL_TRACE:
704 case GTPIE_HOP_CTR:
705 case GTPIE_SEL_PLMN_ID:
706 case GTPIE_MBMS_SESS_ID:
707 case GTPIE_MBMS_2_3G_IND:
708 case GTPIE_ENH_NSAPI:
709 case GTPIE_MBMS_SESS_DUR:
710 case GTPIE_A_MBMS_TRAC_I:
711 case GTPIE_MBMS_S_REP_N:
712 case GTPIE_MBMS_TTDT:
713 case GTPIE_PS_HO_REQ_CTX:
714 case GTPIE_BSS_CONTAINER:
715 case GTPIE_CELL_ID:
716 case GTPIE_PDU_NUMBERS:
717 case GTPIE_BSSGP_CAUSE:
718 case GTPIE_RQD_MBMS_BCAP:
719 case GTPIE_RIM_RA_DISCR:
720 case GTPIE_L_SETUP_PFCS:
721 case GTPIE_PS_HO_XID_PAR:
722 case GTPIE_MS_CHG_REP_A:
723 case GTPIE_DIR_TUN_FLAGS:
724 case GTPIE_CORREL_ID:
725 case GTPIE_MBMS_FLOWI:
726 case GTPIE_MBMS_MC_DIST:
727 case GTPIE_MBMS_DIST_ACK:
728 case GTPIE_R_IRAT_HO_INF:
729 case GTPIE_RFSP_IDX:
730 case GTPIE_FQDN:
731 case GTPIE_E_ALL_PRIO_1:
732 case GTPIE_E_ALL_PRIO_2:
733 case GTPIE_E_CMN_FLAGS:
734 case GTPIE_U_CSG_INFO:
735 case GTPIE_CSG_I_REP_ACT:
736 case GTPIE_CSG_ID:
737 case GTPIE_CSG_MEMB_IND:
738 case GTPIE_AMBR:
739 case GTPIE_UE_NET_CAPA:
740 case GTPIE_UE_AMBR:
741 case GTPIE_APN_AMBR_NS:
742 case GTPIE_GGSN_BACKOFF:
743 case GTPIE_S_PRIO_IND:
744 case GTPIE_S_PRIO_IND_NS:
745 case GTPIE_H_BR_16MBPS_F:
746 case GTPIE_A_MMCTX_SRVCC:
747 case GTPIE_A_FLAGS_SRVCC:
748 case GTPIE_STN_SR:
749 case GTPIE_C_MSISDN:
750 case GTPIE_E_RANAP_CAUSE:
751 case GTPIE_ENODEB_ID:
752 case GTPIE_SEL_MODE_NS:
753 case GTPIE_ULI_TIMESTAMP:
754 case GTPIE_CHARGING_ADDR:
Harald Weltebed35df2011-11-02 13:06:18 +0100755 case GTPIE_PRIVATE:
756 iesize = 3 + hton16(ie[i]->tlv.l);
757 break;
758 default:
759 return 2; /* We received something unknown */
760 }
761 if (p + iesize < end) {
762 memcpy(p, ie[i], iesize);
763 p += iesize;
764 *len += iesize;
765 } else
766 return 2; /* Out of space */
767 }
768 return 0;
jjako52c24142002-12-16 13:33:51 +0000769}
770
Harald Weltec5150ce2017-10-13 06:35:46 +0200771/*! Encode GTP packet payload from Array of Information Elements.
772 * \param[out] ie Input Array of GTPIE
773 * \param[in] size Size of ?
774 * \param[out] pack Pointer to caller-allocated buffer for raw GTP packet (GTPIE_MAX length)
775 * \param[out] len Encoded length of \a pack in bytes
776 * \returns 0 on sucess; 2 for out-of-space */
Harald Weltef54a1f42010-05-04 11:08:38 +0200777int gtpie_encaps2(union gtpie_member ie[], unsigned int size,
Harald Weltebed35df2011-11-02 13:06:18 +0100778 void *pack, unsigned *len)
779{
780 unsigned int i, j;
781 unsigned char *p;
782 unsigned char *end;
Harald Weltebed35df2011-11-02 13:06:18 +0100783 int iesize;
jjako52c24142002-12-16 13:33:51 +0000784
Harald Weltebed35df2011-11-02 13:06:18 +0100785 p = pack;
786
787 memset(pack, 0, GTPIE_MAX);
788 end = p + GTPIE_MAX;
789 for (j = 0; j < GTPIE_SIZE; j++)
790 for (i = 0; i < size; i++)
791 if (ie[i].t == j) {
792 if (GTPIE_DEBUG)
793 printf
794 ("gtpie_encaps. Number %d, Type %d\n",
795 i, ie[i].t);
Harald Weltebed35df2011-11-02 13:06:18 +0100796 switch (ie[i].t) {
797 case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
798 case GTPIE_REORDER:
799 case GTPIE_MAP_CAUSE:
800 case GTPIE_MS_VALIDATED:
801 case GTPIE_RECOVERY:
802 case GTPIE_SELECTION_MODE:
803 case GTPIE_TEARDOWN:
804 case GTPIE_NSAPI:
805 case GTPIE_RANAP_CAUSE:
806 case GTPIE_RP_SMS:
807 case GTPIE_RP:
808 case GTPIE_MS_NOT_REACH:
BJovke03dbafb2016-09-15 13:41:41 +0200809 case GTPIE_BCM:
Harald Weltebed35df2011-11-02 13:06:18 +0100810 iesize = 2;
811 break;
812 case GTPIE_PFI: /* TV GTPIE types with value length 2 */
813 case GTPIE_CHARGING_C:
814 case GTPIE_TRACE_REF:
815 case GTPIE_TRACE_TYPE:
816 iesize = 3;
817 break;
818 case GTPIE_QOS_PROFILE0: /* TV GTPIE types with value length 3 */
819 case GTPIE_P_TMSI_S:
820 iesize = 4;
821 break;
822 case GTPIE_TLLI: /* TV GTPIE types with value length 4 */
823 case GTPIE_P_TMSI:
824 case GTPIE_TEI_DI:
825 case GTPIE_TEI_C:
Harald Weltebc41c8d2017-10-09 10:15:04 +0800826 case GTPIE_CHARGING_ID:
Harald Weltebed35df2011-11-02 13:06:18 +0100827 iesize = 5;
828 break;
829 case GTPIE_TEI_DII: /* TV GTPIE types with value length 5 */
830 iesize = 6;
831 break;
Harald Weltef6c5f952017-10-14 07:56:41 +0200832 case GTPIE_RAI: /* TV GTPIE types with value length 6 */
833 iesize = 7;
834 break;
Harald Weltebed35df2011-11-02 13:06:18 +0100835 case GTPIE_RAB_CONTEXT: /* TV GTPIE types with value length 7 */
836 iesize = 8;
837 break;
838 case GTPIE_IMSI: /* TV GTPIE types with value length 8 */
Harald Weltebed35df2011-11-02 13:06:18 +0100839 iesize = 9;
840 break;
841 case GTPIE_AUTH_TRIPLET: /* TV GTPIE types with value length 28 */
842 iesize = 29;
843 break;
844 case GTPIE_EXT_HEADER_T: /* GTP extension header */
845 iesize = 2 + hton8(ie[i].ext.l);
846 break;
Harald Weltebc41c8d2017-10-09 10:15:04 +0800847 case GTPIE_EUA: /* TLV GTPIE types with length length 2 */
Harald Weltebed35df2011-11-02 13:06:18 +0100848 case GTPIE_MM_CONTEXT:
849 case GTPIE_PDP_CONTEXT:
850 case GTPIE_APN:
851 case GTPIE_PCO:
852 case GTPIE_GSN_ADDR:
853 case GTPIE_MSISDN:
854 case GTPIE_QOS_PROFILE:
855 case GTPIE_AUTH_QUINTUP:
856 case GTPIE_TFT:
857 case GTPIE_TARGET_INF:
858 case GTPIE_UTRAN_TRANS:
859 case GTPIE_RAB_SETUP:
860 case GTPIE_TRIGGER_ID:
861 case GTPIE_OMC_ID:
Harald Weltebc41c8d2017-10-09 10:15:04 +0800862 case GTPIE_RAN_T_CONTAIN:
863 case GTPIE_PDP_CTX_PRIO:
864 case GTPIE_ADDL_RAB_S_I:
865 case GTPIE_SGSN_NUMBER:
Harald Welte89e1abc2017-10-08 07:50:20 +0800866 case GTPIE_COMMON_FLAGS:
Harald Weltebc41c8d2017-10-09 10:15:04 +0800867 case GTPIE_APN_RESTR:
868 case GTPIE_R_PRIO_LCS:
869 case GTPIE_RAT_TYPE:
870 case GTPIE_USER_LOC:
871 case GTPIE_MS_TZ:
872 case GTPIE_IMEI_SV:
873 case GTPIE_CML_CHG_I_CT:
874 case GTPIE_MBMS_UE_CTX:
875 case GTPIE_TMGI:
876 case GTPIE_RIM_ROUT_ADDR:
877 case GTPIE_MBMS_PCO:
878 case GTPIE_MBMS_SA:
879 case GTPIE_SRNC_PDCP_CTX:
880 case GTPIE_ADDL_TRACE:
881 case GTPIE_HOP_CTR:
882 case GTPIE_SEL_PLMN_ID:
883 case GTPIE_MBMS_SESS_ID:
884 case GTPIE_MBMS_2_3G_IND:
885 case GTPIE_ENH_NSAPI:
886 case GTPIE_MBMS_SESS_DUR:
887 case GTPIE_A_MBMS_TRAC_I:
888 case GTPIE_MBMS_S_REP_N:
889 case GTPIE_MBMS_TTDT:
890 case GTPIE_PS_HO_REQ_CTX:
891 case GTPIE_BSS_CONTAINER:
892 case GTPIE_CELL_ID:
893 case GTPIE_PDU_NUMBERS:
894 case GTPIE_BSSGP_CAUSE:
895 case GTPIE_RQD_MBMS_BCAP:
896 case GTPIE_RIM_RA_DISCR:
897 case GTPIE_L_SETUP_PFCS:
898 case GTPIE_PS_HO_XID_PAR:
899 case GTPIE_MS_CHG_REP_A:
900 case GTPIE_DIR_TUN_FLAGS:
901 case GTPIE_CORREL_ID:
902 case GTPIE_MBMS_FLOWI:
903 case GTPIE_MBMS_MC_DIST:
904 case GTPIE_MBMS_DIST_ACK:
905 case GTPIE_R_IRAT_HO_INF:
906 case GTPIE_RFSP_IDX:
907 case GTPIE_FQDN:
908 case GTPIE_E_ALL_PRIO_1:
909 case GTPIE_E_ALL_PRIO_2:
910 case GTPIE_E_CMN_FLAGS:
911 case GTPIE_U_CSG_INFO:
912 case GTPIE_CSG_I_REP_ACT:
913 case GTPIE_CSG_ID:
914 case GTPIE_CSG_MEMB_IND:
915 case GTPIE_AMBR:
916 case GTPIE_UE_NET_CAPA:
917 case GTPIE_UE_AMBR:
918 case GTPIE_APN_AMBR_NS:
919 case GTPIE_GGSN_BACKOFF:
920 case GTPIE_S_PRIO_IND:
921 case GTPIE_S_PRIO_IND_NS:
922 case GTPIE_H_BR_16MBPS_F:
923 case GTPIE_A_MMCTX_SRVCC:
924 case GTPIE_A_FLAGS_SRVCC:
925 case GTPIE_STN_SR:
926 case GTPIE_C_MSISDN:
927 case GTPIE_E_RANAP_CAUSE:
928 case GTPIE_ENODEB_ID:
929 case GTPIE_SEL_MODE_NS:
930 case GTPIE_ULI_TIMESTAMP:
931 case GTPIE_CHARGING_ADDR:
Harald Weltebed35df2011-11-02 13:06:18 +0100932 case GTPIE_PRIVATE:
933 iesize = 3 + hton16(ie[i].tlv.l);
934 break;
935 default:
936 return 2; /* We received something unknown */
937 }
938 if (p + iesize < end) {
939 memcpy(p, &ie[i], iesize);
940 p += iesize;
941 *len += iesize;
942 } else
943 return 2; /* Out of space */
944 }
945 return 0;
jjako52c24142002-12-16 13:33:51 +0000946}