diff --git a/infra/packet_manager/packet_parser.c b/infra/packet_manager/packet_parser.c index e4de9f5..76c4706 100644 --- a/infra/packet_manager/packet_parser.c +++ b/infra/packet_manager/packet_parser.c @@ -819,30 +819,44 @@ static inline const char *parse_gtp_u(struct packet *pkt, const char *data, uint return data; } - uint8_t next_proto = (((const uint8_t *)(data + hdr_len))[0]) >> 4; - if (next_proto != 4 && next_proto != 6) + if (hdr_len == len) { - // next_proto is not IPv4 or IPv6, this is not a normal GTP-U packet, fallback to UDP - return data; - } - - struct layer_private *layer = get_free_layer(pkt); - if (unlikely(layer == NULL)) - { - return data; - } - SET_LAYER(pkt, layer, LAYER_PROTO_GTP_U, hdr_len, data, len, 0); - - switch (next_proto) - { - case 4: - return parse_ipv4(pkt, layer->pld_ptr, layer->pld_len); - case 6: - return parse_ipv6(pkt, layer->pld_ptr, layer->pld_len); - default: - PACKET_LOG_UNSUPPORT_PROTO(pkt, LAYER_PROTO_GTP_U, next_proto); + // only GTP-U header, no payload + struct layer_private *layer = get_free_layer(pkt); + if (unlikely(layer == NULL)) + { + return data; + } + SET_LAYER(pkt, layer, LAYER_PROTO_GTP_U, hdr_len, data, len, 0); return layer->pld_ptr; } + else + { + uint8_t next_proto = (((const uint8_t *)(data + hdr_len))[0]) >> 4; + if (next_proto != 4 && next_proto != 6) + { + // next_proto is not IPv4 or IPv6, this is not a normal GTP-U packet, fallback to UDP + return data; + } + + struct layer_private *layer = get_free_layer(pkt); + if (unlikely(layer == NULL)) + { + return data; + } + SET_LAYER(pkt, layer, LAYER_PROTO_GTP_U, hdr_len, data, len, 0); + + switch (next_proto) + { + case 4: + return parse_ipv4(pkt, layer->pld_ptr, layer->pld_len); + case 6: + return parse_ipv6(pkt, layer->pld_ptr, layer->pld_len); + default: + PACKET_LOG_UNSUPPORT_PROTO(pkt, LAYER_PROTO_GTP_U, next_proto); + return layer->pld_ptr; + } + } } static inline const char *parse_gtp_c(struct packet *pkt, const char *data, uint16_t len)