diff options
-rw-r--r-- | ggsn/ggsn.c | 2 | ||||
-rw-r--r-- | gtp/gtp.c | 28 | ||||
-rw-r--r-- | gtp/gtp.h | 1 |
3 files changed, 30 insertions, 1 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c index 05a56ae..c6a6dac 100644 --- a/ggsn/ggsn.c +++ b/ggsn/ggsn.c @@ -146,7 +146,7 @@ static bool send_trap(const struct gsn_t *gsn, const struct pdp_t *pdp, const st const char *addrstr = in46a_ntop(&member->addr, addrbuf, sizeof(addrbuf)); - snprintf(val, sizeof(val), "%" PRIu64 ",%s", pdp->imsi, addrstr); + snprintf(val, sizeof(val), "%s,%s", imsi_gtp2str(&pdp->imsi), addrstr); if (ctrl_cmd_send_trap(gsn->ctrl, var, val) < 0) { LOGP(DGGSN, LOGL_ERROR, "Failed to create and send TRAP for IMSI %" PRIu64 " [%s].\n", pdp->imsi, var); @@ -3244,3 +3244,31 @@ int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src) memcpy(gsna->v, src, gsna->l); return 0; } + +/* TS 29.060 has yet again a different encoding for IMSIs than + * what we have in other places, so we cannot use the gsm48 + * decoding functions. Also, libgtp uses an uint64_t in + * _network byte order_ to contain BCD digits ?!? */ +const char *imsi_gtp2str(const uint64_t *imsi) +{ + static char buf[sizeof(*imsi)+1]; + const uint8_t *imsi8 = (const uint8_t *) imsi; + unsigned int i, j = 0; + + for (i = 0; i < sizeof(*imsi); i++) { + uint8_t nibble; + + nibble = imsi8[i] & 0xf; + if (nibble == 0xf) + break; + buf[j++] = osmo_bcd2char(nibble); + + nibble = imsi8[i] >> 4; + if (nibble == 0xf) + break; + buf[j++] = osmo_bcd2char(nibble); + } + + buf[j++] = '\0'; + return buf; +} @@ -402,5 +402,6 @@ extern int ipv42eua(struct ul66_t *eua, struct in_addr *src); 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); #endif /* !_GTP_H */ |