This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.
Neels Hofmeyr nhofmeyr at sysmocom.dediff --git a/openbsc/src/gprs/gtphub.c b/openbsc/src/gprs/gtphub.c index e849a8f..73e7c02 100644 --- a/openbsc/src/gprs/gtphub.c +++ b/openbsc/src/gprs/gtphub.c @@ -23,6 +23,7 @@ #include <errno.h> #include <inttypes.h> #include <netinet/in.h> +#include <arpa/inet.h> #include <gtp.h> @@ -33,6 +34,8 @@ #include <osmocom/core/logging.h> #include <osmocom/core/socket.h> +#define GTPHUB_DEBUG 1 + void *osmo_gtphub_ctx; #define LOGERR(fmt, args...) \ @@ -54,6 +57,23 @@ typedef int (*osmo_fd_cb_t)(struct osmo_fd *fd, unsigned int what); #define ntoh16(x) ntohs(x) #define ntoh32(x) ntohl(x) +/* cheat to use gtpie.h API. + * TODO publish gtpie.h upon openggsn installation */ +union gtpie_member; +extern int gtpie_decaps(union gtpie_member *ie[], int version, + void *pack, unsigned len); +extern int gtpie_gettv0(union gtpie_member *ie[], int type, int instance, + void *dst, unsigned int size); +extern int gtpie_gettv1(union gtpie_member *ie[], int type, int instance, + uint8_t *dst); +extern int gtpie_gettlv(union gtpie_member *ie[], int type, int instance, + unsigned int *length, void *dst, unsigned int size); +#define GTPIE_IMSI 2 /* International Mobile Subscriber Identity 8 */ +#define GTPIE_NSAPI 20 /* NSAPI 1 */ +#define GTPIE_GSN_ADDR 133 /* GSN Address */ +#define GTPIE_SIZE 256 +/* end of things needed from gtpie.h */ + /* TODO move GTP header stuff to openggsn/gtp/ ? See gtp_decaps*() */ enum gtp_rc { @@ -72,6 +92,7 @@ struct gtp_packet_desc { int header_len; int version; int rc; + union gtpie_member *ie[GTPIE_SIZE]; }; /* Validate GTP version 0 data; analogous to validate_gtp1_header(), see there. @@ -194,6 +215,45 @@ void validate_gtp_header(struct gtp_packet_desc *p) } } + +/* Return the value of the i'th IMSI IEI by copying to *imsi. + * The first IEI is reached by passing i = 0. + * imsi must point at allocated space of (at least) 8 bytes. + * Return 1 on success, or 0 if not found. */ +static int get_ie_imsi(union gtpie_member *ie[], uint8_t *imsi, int i) +{ + return gtpie_gettv0(ie, GTPIE_IMSI, i, imsi, 8) == 0; +} + +/* Analogous to get_ie_imsi(). nsapi must point at a single uint8_t. */ +static int get_ie_nsapi(union gtpie_member *ie[], uint8_t *nsapi, int i) +{ + return gtpie_gettv1(ie, GTPIE_NSAPI, i, nsapi) == 0; +} + +static char imsi_digit_to_char(uint8_t nibble) +{ + nibble &= 0x0f; + if (nibble > 9) + return (nibble == 0x0f) ? '\0' : '?'; + return '0' + nibble; +} + +/* Return a human readable IMSI string, in a static buffer. + * imsi must point at 8 octets of IMSI IE encoded IMSI data. */ +static const char *imsi_to_str(uint8_t *imsi) +{ + static char str[17]; + int i; + + for (i = 0; i < 8; i++) { + str[2*i] = imsi_digit_to_char(imsi[i]); + str[2*i + 1] = imsi_digit_to_char(imsi[i] >> 4); + } + str[16] = '\0'; + return str; +} + /* Validate header, and index information elements. Write decoded packet * information to *res. res->data will point at the given data buffer. On * error, p->rc is set <= 0 (see enum gtp_rc). */ @@ -207,6 +267,43 @@ static void gtp_decode(const uint8_t *data, int data_len, struct gtp_packet_desc if (res->rc == GTP_RC_TINY) LOG("tiny: no IEs in this GTP packet\n"); + + if (res->rc != GTP_RC_PDU) + return; + + if (gtpie_decaps(res->ie, res->version, + (void*)(data + res->header_len), + res->data_len - res->header_len) != 0) { + res->rc = GTP_RC_INVALID_IE; + return; + } + +#if GTPHUB_DEBUG + int i; + + for (i = 0; i < 10; i++) { + uint8_t imsi[8]; + if (!get_ie_imsi(res->ie, imsi, i)) + break; + LOG("- IMSI %s\n", imsi_to_str(imsi)); + } + + for (i = 0; i < 10; i++) { + uint8_t nsapi; + if (!get_ie_nsapi(res->ie, &nsapi, i)) + break; + LOG("- NSAPI %d\n", (int)nsapi); + } + + for (i = 0; i < 10; i++) { + unsigned int addr_len; + struct in_addr addr; + if (gtpie_gettlv(res->ie, GTPIE_GSN_ADDR, i, &addr_len, &addr, + sizeof(addr)) != 0) + break; + LOG("- addr %s\n", inet_ntoa(addr)); + } +#endif } -- 2.1.4