#pragma once

#include <cstdint>

#include <netinet/in.h>

/* Ethernet/IP/TCP structures for casting */
constexpr ui8 TCP_FIN = 0x01;
constexpr ui8 TCP_SYN = 0x02;
constexpr ui8 TCP_RST = 0x04;
constexpr ui8 TCP_ACK = 0x10;

constexpr ui8 IPV4 = 0x04;
constexpr ui8 IPV6 = 0x06;
/* Basic optional fields */
constexpr ui8 IP6OPT_TCP = 6;
constexpr ui8 IP6OPT_HOP = 0;
constexpr ui8 IP6OPT_ROUTING = 43;
constexpr ui8 IP6OPT_FRAG = 44;
constexpr ui8 IP6OPT_AH = 51;
constexpr ui8 IP6OPT_DST = 60;
constexpr ui8 IP6OPT_MIPV6 = 135;
constexpr ui8 IP6OPT_SHIM6 = 140;

typedef struct {
    unsigned char ipVersion;
    unsigned char skipTOS;
    ui16 skipIpLen;
    ui16 skipIpId;
    ui16 skipOffset;
    unsigned char skipIpTtl;
    unsigned char proto; // TCP 0x06
    ui16 skipChecksum;
    struct in_addr srcIp;
    struct in_addr dstIp;
} TIp4Frame;

typedef struct {
    ui32 skipVersionTrafficClassFlowLabel;
    ui16 skipPayloadLen;
    unsigned char proto;
    unsigned char skipHopLimit;
    struct in6_addr srcIp;
    struct in6_addr dstIp;
} TIp6Frame;

typedef struct {
    unsigned char proto;
    unsigned char skipHdrExtLen;
    /* Skip all other optional fields */
} TIp6FrameNxt;

typedef struct {
    ui16 srcPort;
    ui16 dstPort;
    ui32 seq;
    ui32 ack;
    unsigned char skipOffset;
    unsigned char flags;
    ui16 skipWindow;
    ui16 skipCheckSum;
    ui16 skipUrgent;
} TTcpFrame;
