summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLu Qiuwen <[email protected]>2021-10-27 18:55:49 +0300
committerLu Qiuwen <[email protected]>2021-10-27 18:55:49 +0300
commitcb196c77b90e94bff4c065421d72527243e743ee (patch)
treee00a9fd1b4340184cd9c54990d79d80325f652d5
parent77a697ff32b3b0f9525683e29f2f809cdaa64613 (diff)
增加对GTP拓展报文解析的支持。v4.4.9-20211027
-rw-r--r--infra/include/gtp_header.h23
-rw-r--r--infra/src/ldbc.c98
-rw-r--r--infra/test/TestPacketParser.cc180
3 files changed, 282 insertions, 19 deletions
diff --git a/infra/include/gtp_header.h b/infra/include/gtp_header.h
index f9a23bc..f4e403d 100644
--- a/infra/include/gtp_header.h
+++ b/infra/include/gtp_header.h
@@ -40,6 +40,29 @@ struct gtp1_header
uint32_t tid;
} __attribute__ ((packed));
+#define GTP_MSG_TYPE_T_PDU (0xFF)
+#define GTP_HDR_VER_MASK (0xE0)
+#define GTP_HDR_FLAG_NEXT_EXT_HDR (0x04)
+#define GTP_HDR_FLAG_SEQ_NUM (0x02)
+#define GTP_HDR_FLAG_N_PDU (0x01)
+
+struct gtp_hdr
+{
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned char flags;
+ unsigned char msg_type;
+ unsigned short len;
+ unsigned int teid;
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int teid;
+ unsigned short len;
+ unsigned char msg_type;
+ unsigned char flags;
+#else
+#error "Please check <endian.h>"
+#endif
+};
+
#define GTP1_F_NPDU 0x01
#define GTP1_F_SEQ 0x02
#define GTP1_F_EXTHDR 0x04
diff --git a/infra/src/ldbc.c b/infra/src/ldbc.c
index c99f391..e5604b1 100644
--- a/infra/src/ldbc.c
+++ b/infra/src/ldbc.c
@@ -104,27 +104,73 @@ static const void * __complex_parser_g_vxlan(struct pkt_parser * handler,
return NULL;
}
-static const void * __complex_parser_gtpv1_u(struct pkt_parser * handler,
- const void * data, enum complex_layer this_layer_type)
+/* FROM SAPP */
+static int deal_gtp_calc_gtp_hdr_len(const struct gtp_hdr *gtph)
{
- unsigned int hdrlen = sizeof(struct gtp1_header);
- struct gtp1_header * gtp1;
+ int ext_field_len;
+ const unsigned char *p_ext_hdr = (unsigned char *) gtph + sizeof(struct gtp_hdr);
+ unsigned char next_hdr_type;
+ unsigned char this_ext_field_cont_len;
+
+ /*
+ v0太古老了, 已被废弃;
+ 不存在GTPv2-U协议, 在LTE中的GTP-U仍使用GTPv1-U,
+ 所以, sapp目前仅支持gtp v1版本.
+ */
+
+ if (((gtph->flags & GTP_HDR_VER_MASK) >> 5) != 1)
+ {
+ return -1;
+ }
- gtp1 = (struct gtp1_header *)(data);
- if ((gtp1->flags >> 5) != GTP_VERSION_V1)
- return NULL;
+ if (gtph->flags & (GTP_HDR_FLAG_SEQ_NUM | GTP_HDR_FLAG_N_PDU | GTP_HDR_FLAG_NEXT_EXT_HDR))
+ {
+ //todo, parse and get seq field
+ p_ext_hdr += 2;//seq field length is 2 bytes
- if (gtp1->type != GTP_TPDU)
- return NULL;
+ //todo, parse and get N-PDU field
+ p_ext_hdr++;//N-PDU field length is 1 byte
+
+ /*
+ 解析gtp扩展头部字段,
+ 参考3GPP文档第5.1, 5.2章节,
+ 以及wireshark源码, packet-gtp.c -> dissect_gtp_common()函数.
+ */
+
+ next_hdr_type = *p_ext_hdr;
+ if (gtph->flags & GTP_HDR_FLAG_NEXT_EXT_HDR)
+ {
+ while (next_hdr_type != 0)
+ {
+ //todo, parse and get extension headers
+ p_ext_hdr++;//指向长度字段, 以4个字节为单位
+ this_ext_field_cont_len = *p_ext_hdr * 4 - 2;
+
+ p_ext_hdr++;//指向数据部分第一个字节
+ p_ext_hdr += this_ext_field_cont_len;
+
+ //指向下一个头部字段
+ next_hdr_type = *p_ext_hdr;
+ p_ext_hdr++;
+ }
+ }
+ else
+ {
+ p_ext_hdr++;
+ }
+ }
- /* 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.
- */
- if (gtp1->flags & GTP1_F_MASK)
- hdrlen += 4;
+ return (char *) p_ext_hdr - (char *) gtph;
+}
+
+static const void * __complex_parser_gtpv1_u(struct pkt_parser * handler,
+ const void * data, enum complex_layer this_layer_type)
+{
+ int hdrlen = deal_gtp_calc_gtp_hdr_len((const struct gtp_hdr *)data);
+ if (hdrlen < 0)
+ {
+ return NULL;
+ }
const void * data_next_layer = (const void *)(data + hdrlen);
const uint8_t * __data_next_layer = (const uint8_t *)data_next_layer;
@@ -199,7 +245,23 @@ static const void * __complex_parser_ipv6(struct pkt_parser * handler,
{
if (__parser_exit_or_continue(handler, data, this_layer_type) == PARSE_STOP)
return data;
-
+
+ struct rte_ipv6_hdr * ipv6_hdr = (struct rte_ipv6_hdr *)data;
+ unsigned int ipv6_hdr_len = sizeof(struct rte_ipv6_hdr);
+ void * data_next_layer = (uint8_t *)data + ipv6_hdr_len;
+
+ switch(ipv6_hdr->proto)
+ {
+ case IPPROTO_TCP:
+ return __complex_parser_tcp(handler, data_next_layer, LAYER_TYPE_TCP);
+
+ case IPPROTO_UDP:
+ return __complex_parser_udp(handler, data_next_layer, LAYER_TYPE_UDP);
+
+ default:
+ return NULL;
+ }
+
return NULL;
}
diff --git a/infra/test/TestPacketParser.cc b/infra/test/TestPacketParser.cc
index a52f2b5..062829c 100644
--- a/infra/test/TestPacketParser.cc
+++ b/infra/test/TestPacketParser.cc
@@ -228,6 +228,137 @@ static const unsigned char pkt_mpls_eth[143] = {
0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 /* om..... */
};
+/*
+ * Frame 2: 159 bytes on wire (1272 bits), 159 bytes captured (1272 bits)
+Ethernet II, Src: HuaweiTe_40:e9:c3 (ac:b3:b5:40:e9:c3), Dst: zte_0e:f5:14 (74:4a:a4:0e:f5:14)
+802.1Q Virtual LAN, PRI: 2, DEI: 0, ID: 504
+Internet Protocol Version 6, Src: 2409:8034:4025::10:171, Dst: 2409:8034:4040:5300::206
+ 0110 .... = Version: 6
+ .... 0100 1000 .... .... .... .... .... = Traffic Class: 0x48 (DSCP: AF21, ECN: Not-ECT)
+ .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
+ Payload Length: 101
+ Next Header: UDP (17)
+ Hop Limit: 252
+ Source Address: 2409:8034:4025::10:171
+ Destination Address: 2409:8034:4040:5300::206
+User Datagram Protocol, Src Port: 2152, Dst Port: 2152
+ Source Port: 2152
+ Destination Port: 2152
+ Length: 101
+ Checksum: 0x5242 [unverified]
+ [Checksum Status: Unverified]
+ [Stream index: 2]
+ [Timestamps]
+ UDP payload (93 bytes)
+GPRS Tunneling Protocol
+ Flags: 0x36
+ Message Type: T-PDU (0xff)
+ Length: 85
+ TEID: 0x001b5d7d (1793405)
+ Sequence number: 0x02c1 (705)
+ Next extension header type: PDU Session container (0x85)
+ Extension header (PDU Session container)
+Internet Protocol Version 4, Src: 10.25.188.248, Dst: 112.5.230.54
+User Datagram Protocol, Src Port: 64541, Dst Port: 53
+ Source Port: 64541
+ Destination Port: 53
+ Length: 57
+ Checksum: 0xc2ed [unverified]
+ [Checksum Status: Unverified]
+ [Stream index: 3]
+ [Timestamps]
+ UDP payload (49 bytes)
+Domain Name System (query)
+ */
+static const unsigned char pkt_gtp_u_ext_v6_v4[159] = {
+0x74, 0x4a, 0xa4, 0x0e, 0xf5, 0x14, 0xac, 0xb3, /* tJ...... */
+0xb5, 0x40, 0xe9, 0xc3, 0x81, 0x00, 0x41, 0xf8, /* [email protected]. */
+0x86, 0xdd, 0x64, 0x80, 0x00, 0x00, 0x00, 0x65, /* ..d....e */
+0x11, 0xfc, 0x24, 0x09, 0x80, 0x34, 0x40, 0x25, /* ..$..4@% */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* ........ */
+0x01, 0x71, 0x24, 0x09, 0x80, 0x34, 0x40, 0x40, /* .q$..4@@ */
+0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* S....... */
+0x02, 0x06, 0x08, 0x68, 0x08, 0x68, 0x00, 0x65, /* ...h.h.e */
+0x52, 0x42, 0x36, 0xff, 0x00, 0x55, 0x00, 0x1b, /* RB6..U.. */
+0x5d, 0x7d, 0x02, 0xc1, 0x00, 0x85, 0x01, 0x10, /* ]}...... */
+0x01, 0x00, 0x45, 0x00, 0x00, 0x4d, 0xc2, 0x7f, /* ..E..M.. */
+0x40, 0x00, 0x40, 0x11, 0x5a, 0xd3, 0x0a, 0x19, /* @[email protected]... */
+0xbc, 0xf8, 0x70, 0x05, 0xe6, 0x36, 0xfc, 0x1d, /* ..p..6.. */
+0x00, 0x35, 0x00, 0x39, 0xc2, 0xed, 0x19, 0x9a, /* .5.9.... */
+0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, /* ........ */
+0x00, 0x00, 0x11, 0x70, 0x75, 0x6c, 0x6c, 0x2d, /* ...pull- */
+0x72, 0x74, 0x6d, 0x70, 0x2d, 0x6c, 0x32, 0x36, /* rtmp-l26 */
+0x2d, 0x63, 0x6e, 0x79, 0x09, 0x64, 0x6f, 0x75, /* -cny.dou */
+0x79, 0x69, 0x6e, 0x63, 0x64, 0x6e, 0x03, 0x63, /* yincdn.c */
+0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 /* om..... */
+};
+
+/*
+ * Frame 3: 174 bytes on wire (1392 bits), 174 bytes captured (1392 bits)
+Ethernet II, Src: zte_0e:f5:40 (74:4a:a4:0e:f5:40), Dst: HuaweiTe_62:e5:c0 (60:d7:55:62:e5:c0)
+802.1Q Virtual LAN, PRI: 0, DEI: 0, ID: 503
+Internet Protocol Version 6, Src: 2409:8034:4040:5300::102, Dst: 2409:8034:4025::10:61
+ 0110 .... = Version: 6
+ .... 0000 0000 .... .... .... .... .... = Traffic Class: 0x00 (DSCP: CS0, ECN: Not-ECT)
+ .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
+ Payload Length: 116
+ Next Header: UDP (17)
+ Hop Limit: 127
+ Source Address: 2409:8034:4040:5300::102
+ Destination Address: 2409:8034:4025::10:61
+User Datagram Protocol, Src Port: 2152, Dst Port: 2152
+ Source Port: 2152
+ Destination Port: 2152
+ Length: 116
+ Checksum: 0x96c3 [unverified]
+ [Checksum Status: Unverified]
+ [Stream index: 4]
+ [Timestamps]
+ UDP payload (108 bytes)
+GPRS Tunneling Protocol
+ Flags: 0x34
+ Message Type: T-PDU (0xff)
+ Length: 100
+ TEID: 0x900000cf (2415919311)
+ Next extension header type: PDU Session container (0x85)
+ Extension header (PDU Session container)
+Internet Protocol Version 6, Src: 2409:8034:2000::4, Dst: 2409:8934:4484:1236:60a5:d6ff:fefc:9c59
+ 0110 .... = Version: 6
+ .... 0000 0100 .... .... .... .... .... = Traffic Class: 0x04 (DSCP: LE, ECN: Not-ECT)
+ .... .... .... 0000 0000 0000 0000 0000 = Flow Label: 0x00000
+ Payload Length: 52
+ Next Header: UDP (17)
+ Hop Limit: 56
+ Source Address: 2409:8034:2000::4
+ Destination Address: 2409:8934:4484:1236:60a5:d6ff:fefc:9c59
+User Datagram Protocol, Src Port: 53, Dst Port: 36680
+Domain Name System (response)
+ */
+static const unsigned char pkt_gtp_u_ext_v6_v6[174] = {
+0x60, 0xd7, 0x55, 0x62, 0xe5, 0xc0, 0x74, 0x4a, /* `.Ub..tJ */
+0xa4, 0x0e, 0xf5, 0x40, 0x81, 0x00, 0x01, 0xf7, /* ...@.... */
+0x86, 0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x74, /* ..`....t */
+0x11, 0x7f, 0x24, 0x09, 0x80, 0x34, 0x40, 0x40, /* ..$..4@@ */
+0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* S....... */
+0x01, 0x02, 0x24, 0x09, 0x80, 0x34, 0x40, 0x25, /* ..$..4@% */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, /* ........ */
+0x00, 0x61, 0x08, 0x68, 0x08, 0x68, 0x00, 0x74, /* .a.h.h.t */
+0x96, 0xc3, 0x34, 0xff, 0x00, 0x64, 0x90, 0x00, /* ..4..d.. */
+0x00, 0xcf, 0x00, 0x00, 0x00, 0x85, 0x01, 0x00, /* ........ */
+0x01, 0x00, 0x60, 0x40, 0x00, 0x00, 0x00, 0x34, /* ..`@...4 */
+0x11, 0x38, 0x24, 0x09, 0x80, 0x34, 0x20, 0x00, /* .8$..4 . */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+0x00, 0x04, 0x24, 0x09, 0x89, 0x34, 0x44, 0x84, /* ..$..4D. */
+0x12, 0x36, 0x60, 0xa5, 0xd6, 0xff, 0xfe, 0xfc, /* .6`..... */
+0x9c, 0x59, 0x00, 0x35, 0x8f, 0x48, 0x00, 0x34, /* .Y.5.H.4 */
+0x51, 0x52, 0xe2, 0x9f, 0x81, 0x82, 0x00, 0x01, /* QR...... */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x39, /* .......9 */
+0x39, 0x03, 0x31, 0x38, 0x37, 0x02, 0x34, 0x38, /* 9.187.48 */
+0x03, 0x31, 0x31, 0x32, 0x07, 0x69, 0x6e, 0x2d, /* .112.in- */
+0x61, 0x64, 0x64, 0x72, 0x04, 0x61, 0x72, 0x70, /* addr.arp */
+0x61, 0x00, 0x00, 0x0c, 0x00, 0x01 /* a..... */
+};
+
#define TestCheckIPv4Addr(__result, __str_src_addr, __str_dst_addr) \
do { \
struct rte_ipv4_hdr * _ipv4_hdr = (struct rte_ipv4_hdr *)__result->data; \
@@ -558,6 +689,53 @@ TEST(PacketParseInnerL3, EtherIPv4UDPGTPv1)
TestCheckIPv4Addr(result, "100.80.113.249", "2.78.45.204");
}
+TEST(PacketParseInnerL3, EtherIPv6UDPGTPv1EXTIPv4)
+{
+ struct pkt_parser _pkt_gtp_u_ext_v6_v4_handler;
+ _pkt_gtp_u_ext_v6_v4_handler.expect_layer_type = LAYER_TYPE_L3;
+ _pkt_gtp_u_ext_v6_v4_handler.nr_expect_results = 2;
+ _pkt_gtp_u_ext_v6_v4_handler.nr_results = 0;
+
+ ASSERT_TRUE(complex_parser_ether(&_pkt_gtp_u_ext_v6_v4_handler, pkt_gtp_u_ext_v6_v4) != NULL);
+ EXPECT_EQ(_pkt_gtp_u_ext_v6_v4_handler.nr_results, 2);
+
+ struct pkt_parser_result * result = &_pkt_gtp_u_ext_v6_v4_handler.results[0];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_IPV6);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckIPv6Addr(result, "2409:8034:4025::10:171", "2409:8034:4040:5300::206");
+
+ result = &_pkt_gtp_u_ext_v6_v4_handler.results[1];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_IPV4);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckIPv4Addr(result, "10.25.188.248", "112.5.230.54");
+}
+
+
+TEST(PacketParseInnerL3, EtherIPv6UDPGTPv1EXTIPv6)
+{
+ struct pkt_parser _pkt_gtp_u_ext_v6_v6_handler;
+ _pkt_gtp_u_ext_v6_v6_handler.expect_layer_type = LAYER_TYPE_L3;
+ _pkt_gtp_u_ext_v6_v6_handler.nr_expect_results = 2;
+ _pkt_gtp_u_ext_v6_v6_handler.nr_results = 0;
+
+ ASSERT_TRUE(complex_parser_ether(&_pkt_gtp_u_ext_v6_v6_handler, pkt_gtp_u_ext_v6_v6) != NULL);
+ EXPECT_EQ(_pkt_gtp_u_ext_v6_v6_handler.nr_results, 2);
+
+ struct pkt_parser_result * result = &_pkt_gtp_u_ext_v6_v6_handler.results[0];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_IPV6);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckIPv6Addr(result, "2409:8034:4040:5300::102", "2409:8034:4025::10:61");
+
+ result = &_pkt_gtp_u_ext_v6_v6_handler.results[1];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_IPV6);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckIPv6Addr(result, "2409:8034:2000::4", "2409:8934:4484:1236:60a5:d6ff:fefc:9c59");
+}
+
#if 0
TEST(DistributerInner4, EtherIPv4VxLANIPv4TCP)
{
@@ -635,4 +813,4 @@ TEST(DistributerInner4, EtherIPv4OffloadVxLANIPv4TCP)
}
}
-#endif \ No newline at end of file
+#endif