aboutsummaryrefslogtreecommitdiffstats
path: root/gtp/gtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtp/gtp.c')
-rw-r--r--gtp/gtp.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/gtp/gtp.c b/gtp/gtp.c
index a4e8e2b..012aa79 100644
--- a/gtp/gtp.c
+++ b/gtp/gtp.c
@@ -2581,17 +2581,44 @@ int gtp_error_ind_resp(struct gsn_t *gsn, int version,
int gtp_error_ind_conf(struct gsn_t *gsn, int version,
struct sockaddr_in *peer, void *pack, unsigned len)
{
+ union gtpie_member *ie[GTPIE_SIZE];
struct pdp_t *pdp;
/* Find the context in question */
- if (pdp_tidget(&pdp, be64toh(((union gtp_packet *)pack)->gtp0.h.tid))) {
- gsn->err_unknownpdp++;
- GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
- "Unknown PDP context\n");
- return EOF;
+ if (version == 0) {
+ if (pdp_tidget(&pdp, be64toh(((union gtp_packet *)pack)->gtp0.h.tid))) {
+ gsn->err_unknownpdp++;
+ GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
+ "Unknown PDP context\n");
+ return EOF;
+ }
+ } else if (version == 1) {
+ /* we have to look-up based on the *peer* TEID */
+ int hlen = get_hlen(pack);
+ uint32_t teid_gn;
+
+ /* Decode information elements */
+ if (gtpie_decaps(ie, version, pack + hlen, len - hlen)) {
+ gsn->invalid++;
+ GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
+ "Invalid message format\n");
+ return EOF;
+ }
+
+ if (gtpie_gettv4(ie, GTPIE_TEI_DI, 0, &teid_gn)) {
+ gsn->missing++;
+ GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
+ "Missing mandatory information field\n");
+ return EOF;
+ }
+
+ if (pdp_getgtp1_peer_d(&pdp, peer, teid_gn)) {
+ gsn->err_unknownpdp++;
+ GTP_LOGPKG(LOGL_ERROR, peer, pack, len, "Unknown PDP context\n");
+ return EOF;
+ }
}
- gsn->err_unknownpdp++; /* TODO: Change counter */
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
"Received Error Indication\n");