feature: add GRE utils, support overwrite checksum of GTPv0/GTPv1 header

This commit is contained in:
luwenpeng
2024-07-11 14:26:19 +08:00
parent 6d552acfd0
commit 9e338ffccb
8 changed files with 971 additions and 296 deletions

View File

@@ -25,8 +25,11 @@ target_link_libraries(gtest_vlan_utils packet gtest)
add_executable(gtest_vxlan_utils gtest_vxlan_utils.cpp)
target_link_libraries(gtest_vxlan_utils packet gtest)
add_executable(gtest_gre_utils gtest_gre_utils.cpp)
target_link_libraries(gtest_gre_utils packet gtest)
add_executable(gtest_gre0_utils gtest_gre0_utils.cpp)
target_link_libraries(gtest_gre0_utils packet gtest)
add_executable(gtest_gre1_utils gtest_gre1_utils.cpp)
target_link_libraries(gtest_gre1_utils packet gtest)
add_executable(gtest_l2tp_utils gtest_l2tp_utils.cpp)
target_link_libraries(gtest_l2tp_utils packet gtest)
@@ -59,7 +62,8 @@ gtest_discover_tests(gtest_mpls_utils)
gtest_discover_tests(gtest_eth_utils)
gtest_discover_tests(gtest_vlan_utils)
gtest_discover_tests(gtest_vxlan_utils)
gtest_discover_tests(gtest_gre_utils)
gtest_discover_tests(gtest_gre0_utils)
gtest_discover_tests(gtest_gre1_utils)
gtest_discover_tests(gtest_l2tp_utils)
gtest_discover_tests(gtest_gtp1_utils)
gtest_discover_tests(gtest_gtp2_utils)

View File

@@ -0,0 +1,210 @@
#include <gtest/gtest.h>
#include "gre0_utils.h"
/*
* Generic Routing Encapsulation (IP)
* Flags and Version: 0x0000
* 0... .... .... .... = Checksum Bit: No
* .0.. .... .... .... = Routing Bit: No
* ..0. .... .... .... = Key Bit: No
* ...0 .... .... .... = Sequence Number Bit: No
* .... 0... .... .... = Strict Source Route Bit: No
* .... .000 .... .... = Recursion control: 0
* .... .... 0000 0... = Flags (Reserved): 0
* .... .... .... .000 = Version: GRE (0)
* Protocol Type: IP (0x0800)
*/
unsigned char gre0_no_opt[] = {
0x00, 0x00, 0x08, 0x00};
TEST(GRE0_UTILS, GET_1)
{
const struct gre0_hdr *hdr = (struct gre0_hdr *)gre0_no_opt;
EXPECT_TRUE(gre0_hdr_get_flags(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_checksum_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_routing_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_key_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_seq_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_strict_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_version(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_proto(hdr) == 0x0800);
EXPECT_TRUE(gre0_hdr_get_checksum(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_offset(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_key(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_seq(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_routing_data(hdr) == NULL);
EXPECT_TRUE(gre0_hdr_get_routing_len(hdr) == 0);
EXPECT_TRUE(calc_gre0_hdr_len((const char *)gre0_no_opt, sizeof(gre0_no_opt)) == 4);
}
TEST(GRE0_UTILS, SET_1)
{
char buff[4] = {0};
struct gre0_hdr *hdr = (struct gre0_hdr *)buff;
gre0_hdr_set_flags(hdr, 0);
gre0_hdr_set_checksum_flag(hdr, 0);
gre0_hdr_set_routing_flag(hdr, 0);
gre0_hdr_set_key_flag(hdr, 0);
gre0_hdr_set_seq_flag(hdr, 0);
gre0_hdr_set_strict_flag(hdr, 0);
gre0_hdr_set_version(hdr, 0);
gre0_hdr_set_proto(hdr, 0x0800);
gre0_hdr_set_checksum(hdr, 0);
gre0_hdr_set_offset(hdr, 0);
gre0_hdr_set_key(hdr, 0);
gre0_hdr_set_seq(hdr, 0);
gre0_hdr_set_routing_data(hdr, NULL, 0);
EXPECT_TRUE(memcmp(buff, gre0_no_opt, 4) == 0);
}
/*
* Generic Routing Encapsulation (IP)
* Flags and Version: 0x2000
* 0... .... .... .... = Checksum Bit: No
* .0.. .... .... .... = Routing Bit: No
* ..1. .... .... .... = Key Bit: Yes
* ...0 .... .... .... = Sequence Number Bit: No
* .... 0... .... .... = Strict Source Route Bit: No
* .... .000 .... .... = Recursion control: 0
* .... .... 0000 0... = Flags (Reserved): 0
* .... .... .... .000 = Version: GRE (0)
* Protocol Type: IP (0x0800)
* Key: 0x00000384
*/
unsigned char gre0_opt_key[] = {0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x84};
TEST(GRE0_UTILS, GET_2)
{
const struct gre0_hdr *hdr = (struct gre0_hdr *)gre0_opt_key;
EXPECT_TRUE(gre0_hdr_get_flags(hdr) == 0x2000);
EXPECT_TRUE(gre0_hdr_get_checksum_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_routing_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_key_flag(hdr) == 1);
EXPECT_TRUE(gre0_hdr_get_seq_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_strict_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_version(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_proto(hdr) == 0x0800);
EXPECT_TRUE(gre0_hdr_get_checksum(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_offset(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_key(hdr) == 0x00000384);
EXPECT_TRUE(gre0_hdr_get_seq(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_routing_data(hdr) == NULL);
EXPECT_TRUE(gre0_hdr_get_routing_len(hdr) == 0);
EXPECT_TRUE(calc_gre0_hdr_len((const char *)gre0_opt_key, sizeof(gre0_opt_key)) == 8);
}
TEST(GRE0_UTILS, SET_2)
{
char buff[8] = {0};
struct gre0_hdr *hdr = (struct gre0_hdr *)buff;
gre0_hdr_set_flags(hdr, 0x2000);
gre0_hdr_set_checksum_flag(hdr, 0);
gre0_hdr_set_routing_flag(hdr, 0);
gre0_hdr_set_key_flag(hdr, 1);
gre0_hdr_set_seq_flag(hdr, 0);
gre0_hdr_set_strict_flag(hdr, 0);
gre0_hdr_set_version(hdr, 0);
gre0_hdr_set_proto(hdr, 0x0800);
gre0_hdr_set_checksum(hdr, 0);
gre0_hdr_set_offset(hdr, 0);
gre0_hdr_set_key(hdr, 0x00000384);
gre0_hdr_set_seq(hdr, 0);
gre0_hdr_set_routing_data(hdr, NULL, 0);
EXPECT_TRUE(memcmp(buff, gre0_opt_key, 8) == 0);
}
/*
* Generic Routing Encapsulation (IP)
* Flags and Version: 0xc000
* 1... .... .... .... = Checksum Bit: Yes
* .1.. .... .... .... = Routing Bit: Yes
* ..0. .... .... .... = Key Bit: No
* ...0 .... .... .... = Sequence Number Bit: No
* .... 0... .... .... = Strict Source Route Bit: No
* .... .000 .... .... = Recursion control: 0
* .... .... 0000 0... = Flags (Reserved): 0
* .... .... .... .000 = Version: GRE (0)
* Protocol Type: IP (0x0800)
* Checksum: 0x0000 incorrect, should be 0xea95
* [Expert Info (Warning/Protocol): Incorrect GRE Checksum [should be 0xea95]]
* [Incorrect GRE Checksum [should be 0xea95]]
* [Severity level: Warning]
* [Group: Protocol]
* [Checksum Status: Bad]
* Offset: 44
* Routing
* Address Family: 2
* SRE Offset: 0
* SRE Length: 44
* Routing Information: 6c696e6b5f696e666f206c696e6b5f696e666f206c696e6b5f696e666f206c696e6b5f696e666f2000000000
* Routing
* Address Family: 0
* SRE Offset: 0
* SRE Length: 0
*/
unsigned char gre0_opt_chek_rout[] = {
0xc0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x2c, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x6c, 0x69, 0x6e, 0x6b,
0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
TEST(GRE0_UTILS, GET_3)
{
const struct gre0_hdr *hdr = (struct gre0_hdr *)gre0_opt_chek_rout;
EXPECT_TRUE(gre0_hdr_get_flags(hdr) == 0xc000);
EXPECT_TRUE(gre0_hdr_get_checksum_flag(hdr) == 1);
EXPECT_TRUE(gre0_hdr_get_routing_flag(hdr) == 1);
EXPECT_TRUE(gre0_hdr_get_key_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_seq_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_strict_flag(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_version(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_proto(hdr) == 0x0800);
EXPECT_TRUE(gre0_hdr_get_checksum(hdr) == 0x0000);
EXPECT_TRUE(gre0_hdr_get_offset(hdr) == 44);
EXPECT_TRUE(gre0_hdr_get_key(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_seq(hdr) == 0);
EXPECT_TRUE(gre0_hdr_get_routing_data(hdr) == (const char *)gre0_opt_chek_rout + 8);
EXPECT_TRUE(gre0_hdr_get_routing_len(hdr) == 52);
EXPECT_TRUE(calc_gre0_hdr_len((const char *)gre0_opt_chek_rout, sizeof(gre0_opt_chek_rout)) == 60);
}
TEST(GRE0_UTILS, SET_3)
{
char buff[60] = {0};
struct gre0_hdr *hdr = (struct gre0_hdr *)buff;
gre0_hdr_set_flags(hdr, 0xc000);
gre0_hdr_set_checksum_flag(hdr, 1);
gre0_hdr_set_routing_flag(hdr, 1);
gre0_hdr_set_key_flag(hdr, 0);
gre0_hdr_set_seq_flag(hdr, 0);
gre0_hdr_set_strict_flag(hdr, 0);
gre0_hdr_set_version(hdr, 0);
gre0_hdr_set_proto(hdr, 0x0800);
gre0_hdr_set_checksum(hdr, 0x0000);
gre0_hdr_set_offset(hdr, 44);
gre0_hdr_set_key(hdr, 0);
gre0_hdr_set_seq(hdr, 0);
gre0_hdr_set_routing_data(hdr, (const char *)gre0_opt_chek_rout + 8, 52);
EXPECT_TRUE(memcmp(buff, gre0_opt_chek_rout, 60) == 0);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -0,0 +1,66 @@
#include <gtest/gtest.h>
#include "gre1_utils.h"
/*
* Generic Routing Encapsulation (PPP)
* Flags and Version: 0x3081
* 0... .... .... .... = Checksum Bit: No
* .0.. .... .... .... = Routing Bit: No
* ..1. .... .... .... = Key Bit: Yes
* ...1 .... .... .... = Sequence Number Bit: Yes
* .... 0... .... .... = Strict Source Route Bit: No
* .... .000 .... .... = Recursion control: 0
* .... .... 1... .... = Acknowledgment: Yes
* .... .... .000 0... = Flags (Reserved): 0
* .... .... .... .001 = Version: Enhanced GRE (1)
* Protocol Type: PPP (0x880b)
* Payload Length: 103
* Call ID: 6016
* Sequence Number: 430001
* Acknowledgment Number: 539254
*/
unsigned char gre1_opt_seq_ack[] = {
0x30, 0x81, 0x88, 0x0b, 0x00, 0x67, 0x17, 0x80, 0x00, 0x06, 0x8f, 0xb1, 0x00, 0x08, 0x3a, 0x76};
TEST(GRE1_UTILS, GET_1)
{
const struct gre1_hdr *hdr = (struct gre1_hdr *)gre1_opt_seq_ack;
EXPECT_TRUE(gre1_hdr_get_flags(hdr) == 0x3081);
EXPECT_TRUE(gre1_hdr_get_seq_flag(hdr) == 1);
EXPECT_TRUE(gre1_hdr_get_ack_flag(hdr) == 1);
EXPECT_TRUE(gre1_hdr_get_version(hdr) == 1);
EXPECT_TRUE(gre1_hdr_get_proto(hdr) == 0x880b);
EXPECT_TRUE(gre1_hdr_get_payload_length(hdr) == 103);
EXPECT_TRUE(gre1_hdr_get_call_id(hdr) == 6016);
EXPECT_TRUE(gre1_hdr_get_seq(hdr) == 430001);
EXPECT_TRUE(gre1_hdr_get_ack(hdr) == 539254);
EXPECT_TRUE(calc_gre1_hdr_len((const char *)gre1_opt_seq_ack, sizeof(gre1_opt_seq_ack)) == 16);
}
TEST(GRE1_UTILS, SET_1)
{
char buff[16] = {0};
struct gre1_hdr *hdr = (struct gre1_hdr *)buff;
gre1_hdr_set_flags(hdr, 0x3081);
gre1_hdr_set_seq_flag(hdr, 1);
gre1_hdr_set_ack_flag(hdr, 1);
gre1_hdr_set_version(hdr, 1);
gre1_hdr_set_proto(hdr, 0x880b);
gre1_hdr_set_payload_length(hdr, 103);
gre1_hdr_set_call_id(hdr, 6016);
gre1_hdr_set_seq(hdr, 430001);
gre1_hdr_set_ack(hdr, 539254);
EXPECT_TRUE(memcmp(buff, gre1_opt_seq_ack, 16) == 0);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,136 +0,0 @@
#include <gtest/gtest.h>
#include "gre_utils.h"
/*
* Generic Routing Encapsulation (IP)
* Flags and Version: 0x0000
* 0... .... .... .... = Checksum Bit: No
* .0.. .... .... .... = Routing Bit: No
* ..0. .... .... .... = Key Bit: No
* ...0 .... .... .... = Sequence Number Bit: No
* .... 0... .... .... = Strict Source Route Bit: No
* .... .000 .... .... = Recursion control: 0
* .... .... 0000 0... = Flags (Reserved): 0
* .... .... .... .000 = Version: GRE (0)
* Protocol Type: IP (0x0800)
*/
unsigned char ver0_data1[] = {
0x00, 0x00, 0x08, 0x00};
TEST(GREV0_UTILS, NO_OPTION)
{
const struct gre_hdr *hdr = (struct gre_hdr *)ver0_data1;
EXPECT_TRUE(gre_hdr_get_ver(hdr) == 0);
EXPECT_TRUE(gre_hdr_get_proto(hdr) == 0x0800);
EXPECT_TRUE(calc_gre_hdr_len((const char *)ver0_data1, sizeof(ver0_data1)) == 4);
}
/*
* Generic Routing Encapsulation (IP)
* Flags and Version: 0x2000
* 0... .... .... .... = Checksum Bit: No
* .0.. .... .... .... = Routing Bit: No
* ..1. .... .... .... = Key Bit: Yes
* ...0 .... .... .... = Sequence Number Bit: No
* .... 0... .... .... = Strict Source Route Bit: No
* .... .000 .... .... = Recursion control: 0
* .... .... 0000 0... = Flags (Reserved): 0
* .... .... .... .000 = Version: GRE (0)
* Protocol Type: IP (0x0800)
* Key: 0x00000384
*/
unsigned char ver0_data2[] = {0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x84};
TEST(GREV0_UTILS, KEY_OPTION)
{
const struct gre_hdr *hdr = (struct gre_hdr *)ver0_data2;
EXPECT_TRUE(gre_hdr_get_ver(hdr) == 0);
EXPECT_TRUE(gre_hdr_get_proto(hdr) == 0x0800);
EXPECT_TRUE(calc_gre_hdr_len((const char *)ver0_data2, sizeof(ver0_data2)) == 8);
}
/*
* Generic Routing Encapsulation (IP)
* Flags and Version: 0xc000
* 1... .... .... .... = Checksum Bit: Yes
* .1.. .... .... .... = Routing Bit: Yes
* ..0. .... .... .... = Key Bit: No
* ...0 .... .... .... = Sequence Number Bit: No
* .... 0... .... .... = Strict Source Route Bit: No
* .... .000 .... .... = Recursion control: 0
* .... .... 0000 0... = Flags (Reserved): 0
* .... .... .... .000 = Version: GRE (0)
* Protocol Type: IP (0x0800)
* Checksum: 0x0000 incorrect, should be 0xea95
* [Expert Info (Warning/Protocol): Incorrect GRE Checksum [should be 0xea95]]
* [Incorrect GRE Checksum [should be 0xea95]]
* [Severity level: Warning]
* [Group: Protocol]
* [Checksum Status: Bad]
* Offset: 44
* Routing
* Address Family: 2
* SRE Offset: 0
* SRE Length: 44
* Routing Information: 6c696e6b5f696e666f206c696e6b5f696e666f206c696e6b5f696e666f206c696e6b5f696e666f2000000000
* Routing
* Address Family: 0
* SRE Offset: 0
* SRE Length: 0
*/
unsigned char ver0_data3[] = {
0xc0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x2c, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x6c, 0x69, 0x6e, 0x6b,
0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x20, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x20,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
TEST(GREV0_UTILS, CHECKSUM_ROUTING_OPTION)
{
const struct gre_hdr *hdr = (struct gre_hdr *)ver0_data3;
EXPECT_TRUE(gre_hdr_get_ver(hdr) == 0);
EXPECT_TRUE(gre_hdr_get_proto(hdr) == 0x0800);
EXPECT_TRUE(calc_gre_hdr_len((const char *)ver0_data3, sizeof(ver0_data3)) == 60);
}
/*
* Generic Routing Encapsulation (PPP)
* Flags and Version: 0x3081
* 0... .... .... .... = Checksum Bit: No
* .0.. .... .... .... = Routing Bit: No
* ..1. .... .... .... = Key Bit: Yes
* ...1 .... .... .... = Sequence Number Bit: Yes
* .... 0... .... .... = Strict Source Route Bit: No
* .... .000 .... .... = Recursion control: 0
* .... .... 1... .... = Acknowledgment: Yes
* .... .... .000 0... = Flags (Reserved): 0
* .... .... .... .001 = Version: Enhanced GRE (1)
* Protocol Type: PPP (0x880b)
* Payload Length: 103
* Call ID: 6016
* Sequence Number: 430001
* Acknowledgment Number: 539254
*/
unsigned char ver1_data1[] = {
0x30, 0x81, 0x88, 0x0b, 0x00, 0x67, 0x17, 0x80, 0x00, 0x06, 0x8f, 0xb1, 0x00, 0x08, 0x3a, 0x76};
TEST(GREV1_UTILS, SEQ_ACK_OPTION)
{
const struct gre_hdr *hdr = (struct gre_hdr *)ver1_data1;
EXPECT_TRUE(gre_hdr_get_ver(hdr) == 1);
EXPECT_TRUE(gre_hdr_get_proto(hdr) == 0x880b);
EXPECT_TRUE(calc_gre_hdr_len((const char *)ver1_data1, sizeof(ver1_data1)) == 16);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -5,8 +5,7 @@
#include "udp_utils.h"
#include "ip4_utils.h"
#include "ip6_utils.h"
#include "gtp1_utils.h"
#include "gtp2_utils.h"
#include "gtp_utils.h"
#include "packet_def.h"
#include "packet_dump.h"
#include "packet_layer.h"
@@ -550,12 +549,12 @@ TEST(PACKET_BUILD_TCP, ETH_IP6_UDP_GTP_IP4_TCP)
{
continue;
}
if ((38 <= i && i <= 39) || // skip UDP length
(40 <= i && i <= 41)) // skip UDP checksum
if ((58 <= i && i <= 59) || // skip UDP length
(60 <= i && i <= 61)) // skip UDP checksum
{
continue;
}
if ((44 <= i && i <= 45)) // skip gtp length
if ((64 <= i && i <= 65)) // skip gtp length
{
continue;
}