diff --git a/src/packet/eth_utils.h b/src/packet/eth_utils.h index 3a64db7..30d65fa 100644 --- a/src/packet/eth_utils.h +++ b/src/packet/eth_utils.h @@ -129,6 +129,7 @@ static inline int is_eth_proto(uint16_t proto) case ETH_P_TRAILER: case ETH_P_PHONET: case ETH_P_IEEE802154: + case 0x880B: // PPP:Point-to-Point Protoco return 1; default: return 0; @@ -269,6 +270,8 @@ static inline const char *eth_proto_to_str(uint16_t proto) return "ETH_P_PHONET"; case ETH_P_IEEE802154: return "ETH_P_IEEE802154"; + case 0x880B: + return "PPP"; default: return "ETH_P_UNKNOWN"; } diff --git a/src/packet/gre_utils.h b/src/packet/gre_utils.h new file mode 100644 index 0000000..7050c35 --- /dev/null +++ b/src/packet/gre_utils.h @@ -0,0 +1,187 @@ +#ifndef _GRE_UTILS_H +#define _GRE_UTILS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include "eth_utils.h" + +/* + * GRE Header Format (Version 0) + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |C|R|K|S|s|Recur| Flags | Ver | Protocol Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Checksum (optional) | Offset (optional) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key (optional) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence Number (optional) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Routing (optional) + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Address Family | SRE Offset | SRE Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Routing Information ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * https://datatracker.ietf.org/doc/html/rfc1701 + * https://datatracker.ietf.org/doc/html/rfc2890 + */ + +/* + * Enhanced GRE header (Version 1) + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |C|R|K|S|s|Recur|A| Flags | Ver | Protocol Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Key (HW) Payload Length | Key (LW) Call ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Sequence Number (Optional) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Acknowledgment Number (Optional) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * https://datatracker.ietf.org/doc/html/rfc2637 + */ + +struct gre_hdr +{ + uint16_t flags_ver; + uint16_t protocol; +}; + +struct sre +{ + uint16_t address_family; + uint8_t sre_offset; + uint8_t sre_length; +}; + +#define GRE_CHECKSUM 0x8000 +#define GRE_ROUTING 0x4000 +#define GRE_KEY 0x2000 +#define GRE_SEQUENCE 0x1000 +#define GRE_STRICTSOURCE 0x0800 +#define GRE_RECURSION 0x0700 +#define GRE_ACK 0x0080 /* only in special PPTPized GRE header */ +#define GRE_RESERVED_PPP 0x0078 /* only in special PPTPized GRE header */ +#define GRE_RESERVED 0x00F8 + +/****************************************************************************** + * get + ******************************************************************************/ + +static inline uint8_t gre_hdr_get_ver(const struct gre_hdr *hdr) +{ + return ntohs(hdr->flags_ver) & 0x07; +} + +// ethernet protocol type +static inline uint16_t gre_hdr_get_proto(const struct gre_hdr *hdr) +{ + return ntohs(hdr->protocol); +} + +static inline uint16_t calc_grev0_hdr_len(const char *data, uint32_t len) +{ + const struct gre_hdr *hdr = (const struct gre_hdr *)data; + uint16_t hdr_len = 4; + uint16_t flags = ntohs(hdr->flags_ver); + if ((flags & GRE_CHECKSUM) || (flags & GRE_ROUTING)) + { + hdr_len += 4; // skip checksum and offset fields + } + if (flags & GRE_KEY) + { + hdr_len += 4; // skip key field + } + if (flags & GRE_SEQUENCE) + { + hdr_len += 4; // skip sequence number field + } + if (flags & GRE_ROUTING) + { + while (hdr_len + sizeof(struct sre) <= len) + { + struct sre *sre = (struct sre *)((char *)data + hdr_len); + if (sre->sre_length == 0) + { + hdr_len += sizeof(struct sre); + break; + } + else + { + hdr_len += sizeof(struct sre) + sre->sre_length; + } + } + } + return hdr_len; +} + +static inline uint16_t calc_grev1_hdr_len(const char *data, uint32_t len) +{ + const struct gre_hdr *hdr = (const struct gre_hdr *)data; + uint16_t hdr_len = 8; + uint16_t flags = ntohs(hdr->flags_ver); + if (flags & GRE_SEQUENCE) + { + hdr_len += 4; + } + if (flags & GRE_ACK) + { + hdr_len += 4; + } + return hdr_len; +} + +static inline uint16_t calc_gre_hdr_len(const char *data, uint32_t len) +{ + const struct gre_hdr *hdr = (const struct gre_hdr *)data; + switch (gre_hdr_get_ver(hdr)) + { + case 0: + return calc_grev0_hdr_len(data, len); + case 1: + return calc_grev1_hdr_len(data, len); + default: + return 0; + } +} + +/****************************************************************************** + * set + ******************************************************************************/ + +// TODO + +/****************************************************************************** + * print + ******************************************************************************/ + +static inline int gre_hdr_to_str(const struct gre_hdr *hdr, char *buf, size_t size) +{ + memset(buf, 0, size); + uint16_t proto = gre_hdr_get_proto(hdr); + return snprintf(buf, size, "GRE: version=%u proto=%s", + gre_hdr_get_ver(hdr), eth_proto_to_str(proto)); +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/packet/packet.cpp b/src/packet/packet.cpp index 4ed8cf6..278f6ba 100644 --- a/src/packet/packet.cpp +++ b/src/packet/packet.cpp @@ -6,12 +6,13 @@ #include "uthash.h" #include "packet_priv.h" +#include "eth_utils.h" +#include "gre_utils.h" #include "udp_utils.h" #include "tcp_utils.h" #include "ipv4_utils.h" #include "ipv6_utils.h" #include "mpls_utils.h" -#include "eth_utils.h" #include "vlan_utils.h" #include "vxlan_utils.h" @@ -56,7 +57,6 @@ static inline void set_tuple6(const char *data, enum layer_type type, struct tup static inline struct packet_layer *get_free_layer(struct packet *pkt); static inline uint16_t get_gtp_hdr_len(const char *data, uint16_t len); -static inline uint16_t get_gre_hdr_len(const char *data, uint16_t len); static inline uint16_t get_l2tpv2_hdr_len(const char *data, uint16_t len); // 数据链路层 @@ -354,143 +354,6 @@ static inline uint16_t get_gtp_hdr_len(const char *data, uint16_t len) return hdr_offset; } -static inline uint16_t get_gre_hdr_len(const char *data, uint16_t len) -{ - /* - * GRE Header Format (Version 0) - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |C|R|K|S|s|Recur| Flags | Ver | Protocol Type | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Checksum (optional) | Offset (optional) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Key (optional) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Sequence Number (optional) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Routing (optional) - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Address Family | SRE Offset | SRE Length | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Routing Information ... - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * https://datatracker.ietf.org/doc/html/rfc1701 - * https://datatracker.ietf.org/doc/html/rfc2890 - */ - - /* - * Enhanced GRE header (Version 1) - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * |C|R|K|S|s|Recur|A| Flags | Ver | Protocol Type | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Key (HW) Payload Length | Key (LW) Call ID | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Sequence Number (Optional) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Acknowledgment Number (Optional) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * https://datatracker.ietf.org/doc/html/rfc2637 - */ - -/* bit positions for flags in header */ -#define GRE_CHECKSUM 0x8000 -#define GRE_ROUTING 0x4000 -#define GRE_KEY 0x2000 -#define GRE_SEQUENCE 0x1000 -#define GRE_STRICTSOURCE 0x0800 -#define GRE_RECURSION 0x0700 -#define GRE_ACK 0x0080 /* only in special PPTPized GRE header */ -#define GRE_RESERVED_PPP 0x0078 /* only in special PPTPized GRE header */ -#define GRE_RESERVED 0x00F8 -#define GRE_VERSION 0x0007 - - if (len < 4) - { - return 0; - } - - struct SRE - { - uint16_t address_family; - uint8_t sre_offset; - uint8_t sre_length; - } __attribute__((__packed__)); - - uint16_t sre_size = sizeof(struct SRE); - const uint16_t *gre = (const uint16_t *)data; - uint16_t flags = ntohs(gre[0]); - uint16_t version = flags & GRE_VERSION; - uint16_t hdr_offset = 0; - - if (version == 0) - { - hdr_offset = 4; - - if ((flags & GRE_CHECKSUM) || (flags & GRE_ROUTING)) - { - hdr_offset += 4; - } - if (flags & GRE_KEY) - { - hdr_offset += 4; - } - if (flags & GRE_SEQUENCE) - { - hdr_offset += 4; - } - if (flags & GRE_ROUTING) - { - while (hdr_offset + sre_size <= len) - { - struct SRE *sre = (struct SRE *)((char *)data + hdr_offset); - if (sre->sre_length == 0) - { - hdr_offset += sre_size; - break; - } - else - { - hdr_offset += sre_size + sre->sre_length; - } - } - } - } - else if (version == 1) - { - hdr_offset = 8; - if (flags & GRE_SEQUENCE) - { - hdr_offset += 4; - } - if (flags & GRE_ACK) - { - hdr_offset += 4; - } - } - else - { - return 0; - } - - if (hdr_offset > len) - { - return 0; - } - - return hdr_offset; -} - static inline uint16_t get_l2tpv2_hdr_len(const char *data, uint16_t len) { /* @@ -1049,12 +912,7 @@ static inline const char *parse_auth(struct packet *pkt, const char *data, uint1 static inline const char *parse_gre(struct packet *pkt, const char *data, uint16_t len) { -#define GRE_PRO_IPV4 (0x0800) -#define GRE_PRO_IPV6 (0x86DD) -#define GRE_PRO_ARP (0x0806) -#define GRE_PRO_PPP (0x880B) - - uint16_t hdr_len = get_gre_hdr_len(data, len); + uint16_t hdr_len = calc_gre_hdr_len(data, len); if (unlikely(hdr_len == 0 || hdr_len > len)) { PACKET_LOG_DATA_INSUFFICIENCY(pkt, LAYER_TYPE_GRE); @@ -1066,21 +924,10 @@ static inline const char *parse_gre(struct packet *pkt, const char *data, uint16 { return data; } - uint16_t next_proto = ntohs(*((uint16_t *)data + 1)); + uint16_t next_proto = gre_hdr_get_proto((const struct gre_hdr *)data); SET_LAYER(pkt, layer, LAYER_TYPE_GRE, hdr_len, data, len, 0); - switch (next_proto) - { - case GRE_PRO_IPV4: - return parse_ipv4(pkt, layer->pld_ptr, layer->pld_len); - case GRE_PRO_IPV6: - return parse_ipv6(pkt, layer->pld_ptr, layer->pld_len); - case GRE_PRO_PPP: - return parse_ppp(pkt, layer->pld_ptr, layer->pld_len); - default: - PACKET_LOG_UNSUPPORT_PROTO(pkt, LAYER_TYPE_GRE, next_proto); - return layer->pld_ptr; - } + return parse_l3(pkt, next_proto, layer->pld_ptr, layer->pld_len); } static inline const char *parse_udp(struct packet *pkt, const char *data, uint16_t len) @@ -1283,6 +1130,8 @@ static inline const char *parse_l3(struct packet *pkt, uint16_t next_proto, cons return parse_pppoe_ses(pkt, data, len); case ETH_P_MPLS_UC: return parse_mpls(pkt, data, len); + case 0x880b: + return parse_ppp(pkt, data, len); default: PACKET_LOG_UNSUPPORT_ETHPROTO(pkt, next_proto); return data; @@ -1384,6 +1233,7 @@ void packet_print_str(const struct packet *pkt) case LAYER_TYPE_IPAH: break; case LAYER_TYPE_GRE: + used = gre_hdr_to_str((const struct gre_hdr *)layer->hdr_ptr, buffer, sizeof(buffer)); break; case LAYER_TYPE_UDP: used = udp_hdr_to_str((const struct udphdr *)layer->hdr_ptr, buffer, sizeof(buffer)); diff --git a/src/packet/test/CMakeLists.txt b/src/packet/test/CMakeLists.txt index 867022b..b93656d 100644 --- a/src/packet/test/CMakeLists.txt +++ b/src/packet/test/CMakeLists.txt @@ -25,6 +25,9 @@ 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_packet_frag gtest_packet_frag.cpp) target_link_libraries(gtest_packet_frag packet gtest) @@ -38,4 +41,5 @@ 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_packet_frag) \ No newline at end of file diff --git a/src/packet/test/gtest_gre_utils.cpp b/src/packet/test/gtest_gre_utils.cpp new file mode 100644 index 0000000..f6acdff --- /dev/null +++ b/src/packet/test/gtest_gre_utils.cpp @@ -0,0 +1,136 @@ +#include + +#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(GRE_VER0_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(GRE_VER0_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(GRE_VER0_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(GRE_VER1_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(); +}