Skip to content

Commit 86899f3

Browse files
authored
Merge pull request #58 from salcock/develop
Fix some GTP bugs that were discovered in pre-release testing
2 parents 432c21d + f54c055 commit 86899f3

File tree

1 file changed

+48
-17
lines changed
  • src/collector/accessplugins

1 file changed

+48
-17
lines changed

src/collector/accessplugins/gtp.c

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ typedef struct gtp_session {
142142

143143
char idstr[64];
144144
int idstr_len;
145+
uint32_t teid;
145146

146147
internetaccess_ip_t pdpaddr;
147148
uint16_t pdptype;
@@ -178,6 +179,7 @@ typedef struct gtp_parsed {
178179
uint8_t msgtype;
179180
double tvsec;
180181
uint32_t teid;
182+
uint32_t teid_ctl;
181183
uint32_t seqno;
182184
uint8_t response_cause;
183185

@@ -202,6 +204,7 @@ typedef struct gtp_global {
202204

203205
Pvoid_t saved_packets;
204206
Pvoid_t session_map;
207+
Pvoid_t alt_session_map;
205208

206209
double lastrefresh;
207210
} gtp_global_t;
@@ -214,6 +217,7 @@ static void reset_parsed_pkt(gtp_parsed_t *parsed) {
214217
parsed->msgtype = 0;
215218
parsed->tvsec = 0;
216219
parsed->teid = 0;
220+
parsed->teid_ctl = 0;
217221
parsed->seqno = 0;
218222
parsed->response_cause = 0;
219223

@@ -315,6 +319,7 @@ static void gtp_destroy_plugin_data(access_plugin_t *p) {
315319
JSLN(pval, glob->session_map, index);
316320
}
317321
JSLFA(res, glob->session_map);
322+
JSLFA(res, glob->alt_session_map);
318323

319324
indexnum = 0;
320325
JLF(pval, glob->saved_packets, indexnum);
@@ -576,16 +581,11 @@ static int walk_gtpv1_ies(gtp_parsed_t *parsedpkt, uint8_t *ptr, uint32_t rem,
576581
if (ietype == GTPV1_IE_MSISDN) {
577582
get_gtpnum_from_ie(gtpel, parsedpkt->msisdn, 1);
578583
}
579-
} else if (parsedpkt->msgtype == GTPV1_UPDATE_PDP_CONTEXT_REQUEST) {
580-
if (ietype == GTPV1_IE_TEID_CTRL) {
581-
parsedpkt->teid = get_teid_from_teidctl(gtpel);
582-
}
583-
} else if (parsedpkt->msgtype == GTPV1_DELETE_PDP_CONTEXT_REQUEST) {
584-
if (ietype == GTPV1_IE_TEID_CTRL) {
585-
parsedpkt->teid = get_teid_from_teidctl(gtpel);
586-
}
587584
}
588585

586+
if (ietype == GTPV1_IE_TEID_CTRL) {
587+
parsedpkt->teid_ctl = get_teid_from_teidctl(gtpel);
588+
}
589589

590590
if (ietype == GTPV1_IE_CAUSE) {
591591
parsedpkt->response_cause = get_cause_from_ie(gtpel);
@@ -869,20 +869,34 @@ static void *gtp_parse_packet(access_plugin_t *p, libtrace_packet_t *pkt) {
869869
return glob->parsedpkt;
870870
}
871871

872+
#define GEN_SESSID(sessid, gparsed, teid) \
873+
if (gparsed->serveripfamily == 4) { \
874+
snprintf(sessid, 64, "%u-%u", *(uint32_t *)gparsed->serverid, teid); \
875+
} else if (gparsed->serveripfamily == 6) { \
876+
snprintf(sessid, 64, "%lu-%lu-%u", *(uint64_t *)gparsed->serverid, \
877+
*(uint64_t *)(gparsed->serverid + 8), teid); \
878+
}
879+
872880
static user_identity_t *gtp_get_userid(access_plugin_t *p, void *parsed,
873881
int *numberids) {
874882

875883
gtp_global_t *glob = (gtp_global_t *)(p->plugindata);
876884
gtp_parsed_t *gparsed = (gtp_parsed_t *)parsed;
877885
char sessid[64];
886+
char alt_sessid[64];
878887
gtp_session_t *sess;
879888
PWord_t pval;
880889
user_identity_t *uids;
890+
Pvoid_t search;
881891

882892
if (glob == NULL || gparsed == NULL) {
883893
return NULL;
884894
}
885895

896+
if (gparsed->serveripfamily != 4 && gparsed->serveripfamily != 6) {
897+
return NULL;
898+
}
899+
886900
if (gparsed->matched_session) {
887901
uids = calloc(1, sizeof(user_identity_t));
888902
uids[0].method = USER_IDENT_GTP_MSISDN;
@@ -893,18 +907,15 @@ static user_identity_t *gtp_get_userid(access_plugin_t *p, void *parsed,
893907
}
894908

895909
/* Need to look up the session */
910+
GEN_SESSID(sessid, gparsed, gparsed->teid);
896911

897-
if (gparsed->serveripfamily == 4) {
898-
snprintf(sessid, 64, "%u-%u", *(uint32_t *)gparsed->serverid,
899-
gparsed->teid);
900-
} else if (gparsed->serveripfamily == 6) {
901-
snprintf(sessid, 64, "%lu-%lu-%u", *(uint64_t *)gparsed->serverid,
902-
*(uint64_t *)(gparsed->serverid + 8), gparsed->teid);
912+
if (gparsed->msgtype == GTPV1_DELETE_PDP_CONTEXT_REQUEST) {
913+
search = glob->alt_session_map;
903914
} else {
904-
return NULL;
915+
search = glob->session_map;
905916
}
906917

907-
JSLG(pval, glob->session_map, sessid);
918+
JSLG(pval, search, sessid);
908919

909920
if (pval) {
910921
gparsed->matched_session = (gtp_session_t *)(*pval);
@@ -918,6 +929,25 @@ static user_identity_t *gtp_get_userid(access_plugin_t *p, void *parsed,
918929
strlen(gparsed->matched_session->idstr);
919930
}
920931

932+
if (search == glob->alt_session_map) {
933+
gparsed->teid = gparsed->matched_session->teid;
934+
}
935+
936+
/* v1 delete requests use the teid_cp from the create response
937+
* as their TEID, so we need to have a reference to this session
938+
* for that TEID as well. Otherwise we'll miss the delete requests.
939+
*/
940+
if (gparsed->msgtype == GTPV1_CREATE_PDP_CONTEXT_RESPONSE) {
941+
GEN_SESSID(alt_sessid, gparsed, gparsed->teid_ctl);
942+
JSLG(pval, glob->alt_session_map, alt_sessid);
943+
944+
if (!pval) {
945+
JSLI(pval, glob->alt_session_map, alt_sessid);
946+
*pval = (Word_t)gparsed->matched_session;
947+
}
948+
949+
}
950+
921951
if (gparsed->matched_session->idstr_len == 0) {
922952
*numberids = 0;
923953
return NULL;
@@ -970,6 +1000,7 @@ static user_identity_t *gtp_get_userid(access_plugin_t *p, void *parsed,
9701000
sess = calloc(1, sizeof(gtp_session_t));
9711001
sess->sessid = strdup(sessid);
9721002
sess->current = SESSION_STATE_NEW;
1003+
sess->teid = gparsed->teid;
9731004

9741005
memcpy(sess->serverid, gparsed->serverid, 16);
9751006
sess->serveripfamily = gparsed->serveripfamily;
@@ -1199,7 +1230,7 @@ static void copy_session_params_v2(gtp_parsed_t *gparsed,
11991230
break;
12001231
case GTPV2_IE_MSISDN:
12011232
COPY_SESSION_PARAM(gsess->saved.msisdn, gsess->saved.msisdn_len,
1202-
attrptr, attrlen - 1);
1233+
attrptr, attrlen);
12031234
break;
12041235
case GTPV2_IE_MEI:
12051236
COPY_SESSION_PARAM(gsess->saved.imei, gsess->saved.imei_len,

0 commit comments

Comments
 (0)