diff options
author | Keith <keith@rhizomatica.org> | 2020-10-10 12:17:26 +0200 |
---|---|---|
committer | Keith <keith@rhizomatica.org> | 2020-10-12 13:11:19 +0200 |
commit | cbc07bdd8208a7bdbc251f969fe19c9757cb370b (patch) | |
tree | 6ab93291aca5860a88a59e263f3d29710eeb7691 | |
parent | aedae4c971d5c4f9c5e2ff4b3992b9da02391959 (diff) |
Fix vty PDP lookups by IMSI
The PDP context is searched on the hash which is generated
on context creation from the IMSI in gtp format. - A hash
created from "human-readable" IMSI does not match.
Check user input for length then convert the IMSI to gtp format
before continuing.
Change-Id: Icd2e2bc6068c06fbf5d5fe905ebcda8954f33f04
-rw-r--r-- | ggsn/ggsn_vty.c | 7 | ||||
-rw-r--r-- | gtp/gtp.c | 14 | ||||
-rw-r--r-- | gtp/gtp.h | 1 |
3 files changed, 21 insertions, 1 deletions
diff --git a/ggsn/ggsn_vty.c b/ggsn/ggsn_vty.c index cb92a8a..91ffe4e 100644 --- a/ggsn/ggsn_vty.c +++ b/ggsn/ggsn_vty.c @@ -894,7 +894,12 @@ DEFUN(show_pdpctx_imsi, show_pdpctx_imsi_cmd, return CMD_WARNING; } - imsi = strtoull(argv[1], NULL, 10); + if (strlen(argv[1]) < 6 || strlen(argv[1]) > 15) { + vty_out(vty, "%% Invalid IMSI '%s'%s", argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + + imsi = imsi_str2gtp(argv[1]); if (argc > 2) { nsapi = atoi(argv[2]); @@ -3492,3 +3492,17 @@ const char *imsi_gtp2str(const uint64_t *imsi) buf[j++] = '\0'; 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) +{ + uint64_t ret = 0xf000000000000000ull; + unsigned int i, imsi_length = strlen(imsi); + + for (i = 0; i < imsi_length; i++) + ret |= ((uint64_t) (imsi[i] - '0')) << (i * 4); + return ret; +}
\ No newline at end of file @@ -441,5 +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); #endif /* !_GTP_H */ |