diff options
Diffstat (limited to 'common/src/decode_gtp.c')
| -rw-r--r-- | common/src/decode_gtp.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/common/src/decode_gtp.c b/common/src/decode_gtp.c new file mode 100644 index 0000000..92dc528 --- /dev/null +++ b/common/src/decode_gtp.c @@ -0,0 +1,56 @@ +#include "decode_gtp.h" + +#define GTP_TPDU 255 +#define GTP1U_PORT 2152 +#define GTP1_F_MASK 0x07 + +#define GTP1_GET_TYPE(gtp1_hdr) ((gtp1_hdr)->type) +#define GTP1_GET_FLAGS(gtp1_hdr) ((gtp1_hdr)->flags >> 5) +#define GTP1_GET_HLEN(gtp1_hdr) (((gtp1_hdr)->flags & GTP1_F_MASK) > 0 ? 12 : 8) + +enum gtp_version_e +{ + GTP_V0 = 0, + GTP_V1, +}; + +int decode_gtp(gtp_info_t *packet, const uint8_t *data, uint32_t len) +{ + if (len < sizeof(gtp1_header_t)) + { + LOG_ERROR("Parser GTP Header: packet length too small %d", len); + return -1; + } + + packet->hdr = (gtp1_header_t *)data; + if (GTP1_GET_FLAGS(packet->hdr) != GTP_V1) + { + LOG_ERROR("Parser GTP Header: invalid gtp flags %d", GTP1_GET_FLAGS(packet->hdr)); + return -1; + } + + if (GTP1_GET_TYPE(packet->hdr) != GTP_TPDU) + { + LOG_ERROR("Parser GTP Header: invalid gtp type %d", GTP1_GET_TYPE(packet->hdr)); + return -1; + } + + /* From 29.060: "This field shall be present if and only if any one or + * more of the S, PN and E flags are set.". + * + * If any of the bit is set, then the remaining ones also have to be set. + */ + packet->hdr_len = GTP1_GET_HLEN(packet->hdr); + packet->payload = (uint8_t *)data + packet->hdr_len; + packet->payload_len = len - packet->hdr_len; + + return 0; +} + +void dump_gtp_info(uint32_t pkt_id, gtp_info_t *packet) +{ + LOG_DEBUG("id: %u, gtp_info: {hdr_len: %u, data_len: %u}", + pkt_id, + packet->hdr_len, + packet->payload_len); +}
\ No newline at end of file |
