@@ -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+
872880static 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