diff --git a/ggsn/ggsn_vty.c b/ggsn/ggsn_vty.c index fd2c6ad..f76018e 100644 --- a/ggsn/ggsn_vty.c +++ b/ggsn/ggsn_vty.c @@ -899,7 +899,7 @@ DEFUN(show_pdpctx_imsi, show_pdpctx_imsi_cmd, return CMD_WARNING; } - imsi = imsi_str2gtp(argv[1]); + imsi = gtp_imsi_str2gtp(argv[1]); if (argc > 2) { nsapi = atoi(argv[2]); diff --git a/gtp/gtp.c b/gtp/gtp.c index d4c83d9..25eafdf 100644 --- a/gtp/gtp.c +++ b/gtp/gtp.c @@ -3493,16 +3493,25 @@ const char *imsi_gtp2str(const uint64_t *imsi) return buf; } -/* Encode an IMSI with gtp encoding according to TS 29.060 - the - reverse of imsi_gtp2str(). The hash index used for context - lookups is generated from the IMSI in gtp format. User input - in the vty (for example) needs to be converted to match. */ -const uint64_t imsi_str2gtp(const char *imsi) +/* Generate the GTP IMSI IE according to 09.60 Section 7.9.2 */ +uint64_t gtp_imsi_str2gtp(const char *str) { - uint64_t ret = 0xf000000000000000ull; - unsigned int i, imsi_length = strlen(imsi); + uint64_t imsi64 = 0; + unsigned int n; + unsigned int imsi_len = strlen(str); - for (i = 0; i < imsi_length; i++) - ret |= ((uint64_t) (imsi[i] - '0')) << (i * 4); - return ret; -} \ No newline at end of file + if (imsi_len > 16) { + LOGP(DLGTP, LOGL_NOTICE, "IMSI length > 16 not supported!\n"); + return 0; + } + + for (n = 0; n < 16; n++) { + uint64_t val; + if (n < imsi_len) + val = (str[n]-'0') & 0xf; + else + val = 0xf; + imsi64 |= (val << (n*4)); + } + return imsi64; +} diff --git a/gtp/gtp.h b/gtp/gtp.h index 95566fa..45eb285 100644 --- a/gtp/gtp.h +++ b/gtp/gtp.h @@ -441,6 +441,6 @@ extern int eua2ipv4(struct in_addr *dst, struct ul66_t *eua); extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna); extern int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src); extern const char *imsi_gtp2str(const uint64_t *imsi); -extern const uint64_t imsi_str2gtp(const char *imsi); +extern uint64_t gtp_imsi_str2gtp(const char *str); #endif /* !_GTP_H */ diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c index 002c2e4..7893f4f 100644 --- a/sgsnemu/sgsnemu.c +++ b/sgsnemu/sgsnemu.c @@ -497,7 +497,7 @@ static int process_options(int argc, char **argv) return -1; } - options.imsi = imsi_str2gtp(args_info.imsi_arg); + options.imsi = gtp_imsi_str2gtp(args_info.imsi_arg); printf("IMSI is: %s (%#08llx)\n", args_info.imsi_arg, options.imsi);