#include <gtest/gtest.h>

#include "packet_helper.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();
}
