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/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 */