diff options
| author | Lu Qiuwen <[email protected]> | 2021-10-27 18:55:49 +0300 |
|---|---|---|
| committer | Lu Qiuwen <[email protected]> | 2021-10-27 18:55:49 +0300 |
| commit | cb196c77b90e94bff4c065421d72527243e743ee (patch) | |
| tree | e00a9fd1b4340184cd9c54990d79d80325f652d5 | |
| parent | 77a697ff32b3b0f9525683e29f2f809cdaa64613 (diff) | |
增加对GTP拓展报文解析的支持。v4.4.9-20211027
| -rw-r--r-- | infra/include/gtp_header.h | 23 | ||||
| -rw-r--r-- | infra/src/ldbc.c | 98 | ||||
| -rw-r--r-- | infra/test/TestPacketParser.cc | 180 |
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 |
