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
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 @@
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]);
diff --git a/gtp/gtp.c b/gtp/gtp.c
index ec83041..d4c83d9 100644
--- a/gtp/gtp.c
+++ b/gtp/gtp.c
@@ -3492,3 +3492,17 @@
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
diff --git a/gtp/gtp.h b/gtp/gtp.h
index e03d77d..95566fa 100644
--- a/gtp/gtp.h
+++ b/gtp/gtp.h
@@ -441,5 +441,6 @@
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 */