diff --git a/src/packet/gre0_utils.h b/src/packet/gre0_utils.h new file mode 100644 index 0000000..3bed6f3 --- /dev/null +++ b/src/packet/gre0_utils.h @@ -0,0 +1,421 @@ +#pragma once + +#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 + */ + +struct gre0_hdr +{ + uint16_t flags; + uint16_t protocol; +}; + +struct sre +{ + uint16_t family; + uint8_t offset; + uint8_t length; +}; + +#define GRE0_FLAG_CHECKSUM 0x8000 +#define GRE0_FLAG_ROUTING 0x4000 +#define GRE0_FLAG_KEY 0x2000 +#define GRE0_FLAG_SEQUENCE 0x1000 +#define GRE0_FLAG_STRICT 0x0800 +#define GRE0_FLAG_RECURSION 0x0700 +#define GRE0_FLAG_VERSION 0x0007 + +/****************************************************************************** + * get + ******************************************************************************/ + +static inline uint16_t gre0_hdr_get_flags(const struct gre0_hdr *hdr) +{ + return ntohs(hdr->flags); +} + +static inline uint8_t gre0_hdr_get_checksum_flag(const struct gre0_hdr *hdr) +{ + return (ntohs(hdr->flags) & GRE0_FLAG_CHECKSUM) >> 15; +} + +static inline uint8_t gre0_hdr_get_routing_flag(const struct gre0_hdr *hdr) +{ + return (ntohs(hdr->flags) & GRE0_FLAG_ROUTING) >> 14; +} + +static inline uint8_t gre0_hdr_get_key_flag(const struct gre0_hdr *hdr) +{ + return (ntohs(hdr->flags) & GRE0_FLAG_KEY) >> 13; +} + +static inline uint8_t gre0_hdr_get_seq_flag(const struct gre0_hdr *hdr) +{ + return (ntohs(hdr->flags) & GRE0_FLAG_SEQUENCE) >> 12; +} + +static inline uint8_t gre0_hdr_get_strict_flag(const struct gre0_hdr *hdr) +{ + return (ntohs(hdr->flags) & GRE0_FLAG_STRICT) >> 11; +} + +static inline uint8_t gre0_hdr_get_version(const struct gre0_hdr *hdr) +{ + return ntohs(hdr->flags) & GRE0_FLAG_VERSION; +} + +// ethernet protocol +static inline uint16_t gre0_hdr_get_proto(const struct gre0_hdr *hdr) +{ + return ntohs(hdr->protocol); +} + +static inline uint16_t gre0_hdr_get_checksum(const struct gre0_hdr *hdr) +{ + if (gre0_hdr_get_checksum_flag(hdr)) + { + const char *ptr = ((const char *)hdr) + 4; + return ntohs(*(uint16_t *)ptr); + } + else + { + return 0; + } +} + +static inline uint16_t gre0_hdr_get_offset(const struct gre0_hdr *hdr) +{ + if (gre0_hdr_get_checksum_flag(hdr)) + { + const char *ptr = ((const char *)hdr) + 6; + return ntohs(*(uint16_t *)ptr); + } + else + { + return 0; + } +} + +static inline uint32_t gre0_hdr_get_key(const struct gre0_hdr *hdr) +{ + if (gre0_hdr_get_key_flag(hdr)) + { + const char *ptr = ((const char *)hdr) + 4; + if (gre0_hdr_get_checksum_flag(hdr)) + { + ptr += 4; + } + + return ntohl(*(uint32_t *)ptr); + } + else + { + return 0; + } +} + +static inline uint32_t gre0_hdr_get_seq(const struct gre0_hdr *hdr) +{ + if (gre0_hdr_get_seq_flag(hdr)) + { + const char *ptr = ((const char *)hdr) + 4; + if (gre0_hdr_get_checksum_flag(hdr)) + { + ptr += 4; + } + + if (gre0_hdr_get_key_flag(hdr)) + { + ptr += 4; + } + + return ntohl(*(uint32_t *)ptr); + } + else + { + return 0; + } +} + +static inline const char *gre0_hdr_get_routing_data(const struct gre0_hdr *hdr) +{ + if (gre0_hdr_get_routing_flag(hdr)) + { + const char *ptr = ((const char *)hdr) + 4; + if (gre0_hdr_get_checksum_flag(hdr)) + { + ptr += 4; + } + + if (gre0_hdr_get_key_flag(hdr)) + { + ptr += 4; + } + + if (gre0_hdr_get_seq_flag(hdr)) + { + ptr += 4; + } + + return ptr; + } + else + { + return NULL; + } +} + +static inline uint16_t gre0_hdr_get_routing_len(const struct gre0_hdr *hdr) +{ + if (gre0_hdr_get_routing_flag(hdr)) + { + const char *ptr = gre0_hdr_get_routing_data(hdr); + + uint16_t hdr_len = 0; + while (1) + { + struct sre *sre = (struct sre *)(ptr + hdr_len); + if (sre->length == 0) + { + hdr_len += sizeof(struct sre); + break; + } + else + { + hdr_len += sizeof(struct sre) + sre->length; + } + } + return hdr_len; + } + else + { + return 0; + } +} + +static inline uint16_t calc_gre0_hdr_len(const char *data, uint32_t len) +{ + const struct gre0_hdr *hdr = (const struct gre0_hdr *)data; + uint16_t hdr_len = 4; + uint16_t flags = ntohs(hdr->flags); + if ((flags & GRE0_FLAG_CHECKSUM) || (flags & GRE0_FLAG_ROUTING)) + { + hdr_len += 4; // skip checksum and offset fields + } + if (flags & GRE0_FLAG_KEY) + { + hdr_len += 4; // skip key field + } + if (flags & GRE0_FLAG_SEQUENCE) + { + hdr_len += 4; // skip sequence number field + } + if (flags & GRE0_FLAG_ROUTING) + { + while (hdr_len + sizeof(struct sre) <= len) + { + struct sre *sre = (struct sre *)((char *)data + hdr_len); + if (sre->length == 0) + { + hdr_len += sizeof(struct sre); + break; + } + else + { + hdr_len += sizeof(struct sre) + sre->length; + } + } + } + return hdr_len; +} + +/****************************************************************************** + * set + ******************************************************************************/ + +static inline void gre0_hdr_set_flags(struct gre0_hdr *hdr, uint16_t flags) +{ + hdr->flags = htons(flags); +} + +static inline void gre0_hdr_set_checksum_flag(struct gre0_hdr *hdr, uint8_t flag) +{ + hdr->flags = htons((ntohs(hdr->flags) & ~GRE0_FLAG_CHECKSUM) | flag << 15); +} + +static inline void gre0_hdr_set_routing_flag(struct gre0_hdr *hdr, uint8_t flag) +{ + hdr->flags = htons((ntohs(hdr->flags) & ~GRE0_FLAG_ROUTING) | flag << 14); +} + +static inline void gre0_hdr_set_key_flag(struct gre0_hdr *hdr, uint8_t flag) +{ + hdr->flags = htons((ntohs(hdr->flags) & ~GRE0_FLAG_KEY) | flag << 13); +} + +static inline void gre0_hdr_set_seq_flag(struct gre0_hdr *hdr, uint8_t flag) +{ + hdr->flags = htons((ntohs(hdr->flags) & ~GRE0_FLAG_SEQUENCE) | flag << 12); +} + +static inline void gre0_hdr_set_strict_flag(struct gre0_hdr *hdr, uint8_t flag) +{ + hdr->flags = htons((ntohs(hdr->flags) & ~GRE0_FLAG_STRICT) | flag << 11); +} + +static inline void gre0_hdr_set_version(struct gre0_hdr *hdr, uint8_t version) +{ + hdr->flags = htons((ntohs(hdr->flags) & ~GRE0_FLAG_VERSION) | version); +} + +static inline void gre0_hdr_set_proto(struct gre0_hdr *hdr, uint16_t proto) +{ + hdr->protocol = htons(proto); +} + +static inline void gre0_hdr_set_checksum(struct gre0_hdr *hdr, uint16_t checksum) +{ + if (gre0_hdr_get_checksum_flag(hdr)) + { + char *ptr = ((char *)hdr) + 4; + *(uint16_t *)ptr = htons(checksum); + } +} + +static inline void gre0_hdr_set_offset(struct gre0_hdr *hdr, uint16_t offset) +{ + if (gre0_hdr_get_checksum_flag(hdr)) + { + char *ptr = ((char *)hdr) + 6; + *(uint16_t *)ptr = htons(offset); + } +} + +static inline void gre0_hdr_set_key(struct gre0_hdr *hdr, uint32_t key) +{ + if (gre0_hdr_get_key_flag(hdr)) + { + char *ptr = ((char *)hdr) + 4; + if (gre0_hdr_get_checksum_flag(hdr)) + { + ptr += 4; + } + + *(uint32_t *)ptr = htonl(key); + } +} + +static inline void gre0_hdr_set_seq(struct gre0_hdr *hdr, uint32_t sequence) +{ + if (gre0_hdr_get_seq_flag(hdr)) + { + char *ptr = ((char *)hdr) + 4; + if (gre0_hdr_get_checksum_flag(hdr)) + { + ptr += 4; + } + + if (gre0_hdr_get_key_flag(hdr)) + { + ptr += 4; + } + + *(uint32_t *)ptr = htonl(sequence); + } +} + +static inline void gre0_hdr_set_routing_data(struct gre0_hdr *hdr, const char *data, uint16_t len) +{ + if (gre0_hdr_get_routing_flag(hdr)) + { + char *ptr = ((char *)hdr) + 4; + if (gre0_hdr_get_checksum_flag(hdr)) + { + ptr += 4; + } + + if (gre0_hdr_get_key_flag(hdr)) + { + ptr += 4; + } + + if (gre0_hdr_get_seq_flag(hdr)) + { + ptr += 4; + } + + memcpy(ptr, data, len); + } +} + +/****************************************************************************** + * print + ******************************************************************************/ + +static inline int gre0_hdr_to_str(const struct gre0_hdr *hdr, char *buf, size_t size) +{ + memset(buf, 0, size); + + int used = 0; + uint16_t proto = gre0_hdr_get_proto(hdr); + used += snprintf(buf + used, size - used, "GRE: flags=0x%04x (checksum_flag=%u, routing_flag=%u, key_flag=%u, seq_flag=%u, strict_flag=%u, version=%u), proto=%s", + gre0_hdr_get_flags(hdr), gre0_hdr_get_checksum_flag(hdr), gre0_hdr_get_routing_flag(hdr), gre0_hdr_get_key_flag(hdr), + gre0_hdr_get_seq_flag(hdr), gre0_hdr_get_strict_flag(hdr), gre0_hdr_get_version(hdr), eth_proto_to_str(proto)); + if (gre0_hdr_get_checksum_flag(hdr)) + { + used += snprintf(buf + used, size - used, ", checksum=%u, offset=%u", gre0_hdr_get_checksum(hdr), gre0_hdr_get_offset(hdr)); + } + if (gre0_hdr_get_key_flag(hdr)) + { + used += snprintf(buf + used, size - used, ", key=%u", gre0_hdr_get_key(hdr)); + } + if (gre0_hdr_get_seq_flag(hdr)) + { + used += snprintf(buf + used, size - used, ", seq=%u", gre0_hdr_get_seq(hdr)); + } + if (gre0_hdr_get_routing_flag(hdr)) + { + used += snprintf(buf + used, size - used, ", routing_len=%u", gre0_hdr_get_routing_len(hdr)); + } + + return used; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/packet/gre1_utils.h b/src/packet/gre1_utils.h new file mode 100644 index 0000000..5b8b62a --- /dev/null +++ b/src/packet/gre1_utils.h @@ -0,0 +1,222 @@ +#pragma once + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include +#include "eth_utils.h" + +/* + * 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 gre1_hdr +{ + uint16_t flags; + uint16_t protocol; + uint16_t payload_length; + uint16_t call_id; +}; + +#define GRE1_FLAG_CHECKSUM 0x8000 +#define GRE1_FLAG_ROUTING 0x4000 +#define GRE1_FLAG_KEY 0x2000 +#define GRE1_FLAG_SEQUENCE 0x1000 +#define GRE1_FLAG_STRICT 0x0800 +#define GRE1_FLAG_RECURSION 0x0700 +#define GRE1_FLAG_ACK 0x0080 /* only in special PPTPized GRE header */ +#define GRE1_FLAG_VERSION 0x0007 + +/****************************************************************************** + * get + ******************************************************************************/ + +static inline uint16_t gre1_hdr_get_flags(const struct gre1_hdr *hdr) +{ + return ntohs(hdr->flags); +} + +static inline uint8_t gre1_hdr_get_seq_flag(const struct gre1_hdr *hdr) +{ + return (ntohs(hdr->flags) & GRE1_FLAG_SEQUENCE) >> 12; +} + +static inline uint8_t gre1_hdr_get_ack_flag(const struct gre1_hdr *hdr) +{ + return (ntohs(hdr->flags) & GRE1_FLAG_ACK) >> 7; +} + +static inline uint8_t gre1_hdr_get_version(const struct gre1_hdr *hdr) +{ + return ntohs(hdr->flags) & GRE1_FLAG_VERSION; +} + +// ethernet protocol type +static inline uint16_t gre1_hdr_get_proto(const struct gre1_hdr *hdr) +{ + return ntohs(hdr->protocol); +} + +static inline uint16_t gre1_hdr_get_payload_length(const struct gre1_hdr *hdr) +{ + return ntohs(hdr->payload_length); +} + +static inline uint16_t gre1_hdr_get_call_id(const struct gre1_hdr *hdr) +{ + return ntohs(hdr->call_id); +} + +static inline uint32_t gre1_hdr_get_seq(const struct gre1_hdr *hdr) +{ + if (gre1_hdr_get_seq_flag(hdr)) + { + const char *ptr = ((const char *)hdr) + 8; + return ntohl(*((uint32_t *)ptr)); + } + else + { + return 0; + } +} + +static inline uint32_t gre1_hdr_get_ack(const struct gre1_hdr *hdr) +{ + if (gre1_hdr_get_ack_flag(hdr)) + { + const char *ptr = ((const char *)hdr) + 8; + if (gre1_hdr_get_seq_flag(hdr)) + { + ptr += 4; + } + return ntohl(*((uint32_t *)ptr)); + } + else + { + return 0; + } +} + +static inline uint16_t calc_gre1_hdr_len(const char *data, uint32_t len) +{ + const struct gre1_hdr *hdr = (const struct gre1_hdr *)data; + uint16_t hdr_len = 8; + uint16_t flags = gre1_hdr_get_flags(hdr); + if (flags & GRE1_FLAG_SEQUENCE) + { + hdr_len += 4; + } + if (flags & GRE1_FLAG_ACK) + { + hdr_len += 4; + } + return hdr_len; +} + +/****************************************************************************** + * set + ******************************************************************************/ + +static inline void gre1_hdr_set_flags(struct gre1_hdr *hdr, uint16_t flags) +{ + hdr->flags = htons(flags); +} + +static inline void gre1_hdr_set_seq_flag(struct gre1_hdr *hdr, uint8_t seq_flag) +{ + hdr->flags = htons((ntohs(hdr->flags) & ~GRE1_FLAG_SEQUENCE) | seq_flag << 12); +} + +static inline void gre1_hdr_set_ack_flag(struct gre1_hdr *hdr, uint8_t ack_flag) +{ + hdr->flags = htons((ntohs(hdr->flags) & ~GRE1_FLAG_ACK) | ack_flag << 7); +} + +static inline void gre1_hdr_set_version(struct gre1_hdr *hdr, uint8_t version) +{ + hdr->flags = htons((ntohs(hdr->flags) & ~GRE1_FLAG_VERSION) | version); +} + +static inline void gre1_hdr_set_proto(struct gre1_hdr *hdr, uint16_t proto) +{ + hdr->protocol = htons(proto); +} + +static inline void gre1_hdr_set_payload_length(struct gre1_hdr *hdr, uint16_t payload_length) +{ + hdr->payload_length = htons(payload_length); +} + +static inline void gre1_hdr_set_call_id(struct gre1_hdr *hdr, uint16_t call_id) +{ + hdr->call_id = htons(call_id); +} + +static inline void gre1_hdr_set_seq(struct gre1_hdr *hdr, uint32_t seq) +{ + if (gre1_hdr_get_seq_flag(hdr)) + { + char *ptr = ((char *)hdr) + 8; + *((uint32_t *)ptr) = htonl(seq); + } +} + +static inline void gre1_hdr_set_ack(struct gre1_hdr *hdr, uint32_t ack) +{ + if (gre1_hdr_get_ack_flag(hdr)) + { + char *ptr = ((char *)hdr) + 8; + if (gre1_hdr_get_seq_flag(hdr)) + { + ptr += 4; + } + *((uint32_t *)ptr) = htonl(ack); + } +} + +/****************************************************************************** + * print + ******************************************************************************/ + +static inline int gre1_hdr_to_str(const struct gre1_hdr *hdr, char *buf, size_t size) +{ + memset(buf, 0, size); + + int used = 0; + uint16_t proto = gre1_hdr_get_proto(hdr); + used += snprintf(buf + used, size - used, "GRE: flags=0x%04x (seq_flag=%u ack_flag=%u version=%u), proto=%s, payload_length=%u, call_id=%u", + gre1_hdr_get_flags(hdr), gre1_hdr_get_seq_flag(hdr), gre1_hdr_get_ack_flag(hdr), gre1_hdr_get_version(hdr), + eth_proto_to_str(proto), gre1_hdr_get_payload_length(hdr), gre1_hdr_get_call_id(hdr)); + if (gre1_hdr_get_seq_flag(hdr)) + { + used += snprintf(buf + used, size - used, ", seq=%u", gre1_hdr_get_seq(hdr)); + } + if (gre1_hdr_get_ack_flag(hdr)) + { + used += snprintf(buf + used, size - used, ", ack=%u", gre1_hdr_get_ack(hdr)); + } + + return used; +} + +#ifdef __cplusplus +} +#endif diff --git a/src/packet/gre_utils.h b/src/packet/gre_utils.h index b71b103..640fcec 100644 --- a/src/packet/gre_utils.h +++ b/src/packet/gre_utils.h @@ -5,174 +5,63 @@ extern "C" { #endif -#include -#include -#include -#include "eth_utils.h" +#include "gre0_utils.h" +#include "gre1_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 - */ +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#endif -/* - * 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 +// return GRE version 0 or 1 +// return 255 if not GRE +static inline uint8_t peek_gre_version(const char *data, uint32_t len) { - uint16_t flags_ver; - uint16_t protocol; -}; + if (len < MIN(sizeof(struct gre0_hdr), sizeof(struct gre1_hdr))) + { + return 255; + } -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_ACK 0x0080 /* only in special PPTPized GRE header */ - -/****************************************************************************** - * get - ******************************************************************************/ - -static inline uint8_t gre_hdr_get_ver(const struct gre_hdr *hdr) -{ - return ntohs(hdr->flags_ver) & 0x07; + uint16_t flag = *(uint16_t *)data; + return ntohs(flag) & 0x0007; } -// ethernet protocol type -static inline uint16_t gre_hdr_get_proto(const struct gre_hdr *hdr) +static inline uint16_t peek_gre_proto(const char *data, uint32_t len) { - 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)) + switch (peek_gre_version(data, len)) { case 0: - return calc_grev0_hdr_len(data, len); + return gre0_hdr_get_proto((const struct gre0_hdr *)data); case 1: - return calc_grev1_hdr_len(data, len); + return gre1_hdr_get_proto((const struct gre1_hdr *)data); default: return 0; } } -/****************************************************************************** - * set - ******************************************************************************/ - -// TODO - -/****************************************************************************** - * print - ******************************************************************************/ - -static inline int gre_hdr_to_str(const struct gre_hdr *hdr, char *buf, size_t size) +static inline uint16_t calc_gre_hdr_len(const char *data, uint32_t len) { - 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)); + switch (peek_gre_version(data, len)) + { + case 0: + return calc_gre0_hdr_len(data, len); + case 1: + return calc_gre1_hdr_len(data, len); + default: + return 0; + } +} + +static inline int gre_hdr_to_str(const char *hdr, uint16_t len, char *buf, size_t size) +{ + switch (peek_gre_version(hdr, len)) + { + case 0: + return gre0_hdr_to_str((const struct gre0_hdr *)hdr, buf, size); + case 1: + return gre1_hdr_to_str((const struct gre1_hdr *)hdr, buf, size); + default: + return 0; + } } #ifdef __cplusplus diff --git a/src/packet/test/CMakeLists.txt b/src/packet/test/CMakeLists.txt index 1ab0551..d4baacc 100644 --- a/src/packet/test/CMakeLists.txt +++ b/src/packet/test/CMakeLists.txt @@ -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) diff --git a/src/packet/test/gtest_gre0_utils.cpp b/src/packet/test/gtest_gre0_utils.cpp new file mode 100644 index 0000000..03852c0 --- /dev/null +++ b/src/packet/test/gtest_gre0_utils.cpp @@ -0,0 +1,210 @@ +#include + +#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(); +} diff --git a/src/packet/test/gtest_gre1_utils.cpp b/src/packet/test/gtest_gre1_utils.cpp new file mode 100644 index 0000000..cb91e12 --- /dev/null +++ b/src/packet/test/gtest_gre1_utils.cpp @@ -0,0 +1,66 @@ +#include + +#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(); +} diff --git a/src/packet/test/gtest_gre_utils.cpp b/src/packet/test/gtest_gre_utils.cpp deleted file mode 100644 index 2f65aac..0000000 --- a/src/packet/test/gtest_gre_utils.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#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(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(); -} diff --git a/src/packet/test/gtest_packet_build.cpp b/src/packet/test/gtest_packet_build.cpp index 128d1cf..f59a2e1 100644 --- a/src/packet/test/gtest_packet_build.cpp +++ b/src/packet/test/gtest_packet_build.cpp @@ -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; }