#pragma once

#ifdef __cplusplus
extern "C"
{
#endif

#include <arpa/inet.h>

union ip_address
{
    struct in_addr v4;  /* network order */
    struct in6_addr v6; /* network order */
};

struct tuple2
{
    uint32_t addr_family;
    union ip_address src_addr; /* network order */
    union ip_address dst_addr; /* network order */
};

struct tuple4
{
    uint32_t addr_family;
    union ip_address src_addr; /* network order */
    union ip_address dst_addr; /* network order */

    in_port_t src_port; /* network order */
    in_port_t dst_port; /* network order */
};

struct tuple5
{
    uint32_t addr_family;
    union ip_address src_addr; /* network order */
    union ip_address dst_addr; /* network order */

    in_port_t src_port; /* network order */
    in_port_t dst_port; /* network order */

    uint16_t ip_proto; /* network order */
};

struct tuple6
{
    uint32_t addr_family;
    union ip_address src_addr; /* network order */
    union ip_address dst_addr; /* network order */

    uint16_t src_port; /* network order */
    uint16_t dst_port; /* network order */

    uint16_t ip_proto; /* network order */
    uint64_t domain;
};

uint32_t tuple2_hash(const struct tuple2 *tuple);
uint32_t tuple4_hash(const struct tuple4 *tuple);
uint32_t tuple5_hash(const struct tuple5 *tuple);
uint32_t tuple6_hash(const struct tuple6 *tuple);

int tuple2_cmp(const struct tuple2 *tuple_a, const struct tuple2 *tuple_b);
int tuple4_cmp(const struct tuple4 *tuple_a, const struct tuple4 *tuple_b);
int tuple5_cmp(const struct tuple5 *tuple_a, const struct tuple5 *tuple_b);
int tuple6_cmp(const struct tuple6 *tuple_a, const struct tuple6 *tuple_b);

void tuple2_reverse(const struct tuple2 *in, struct tuple2 *out);
void tuple4_reverse(const struct tuple4 *in, struct tuple4 *out);
void tuple5_reverse(const struct tuple5 *in, struct tuple5 *out);
void tuple6_reverse(const struct tuple6 *in, struct tuple6 *out);

void tuple2_to_str(const struct tuple2 *tuple, char *buf, uint32_t size);
void tuple4_to_str(const struct tuple4 *tuple, char *buf, uint32_t size);
void tuple5_to_str(const struct tuple5 *tuple, char *buf, uint32_t size);
void tuple6_to_str(const struct tuple6 *tuple, char *buf, uint32_t size);

#ifdef __cplusplus
}
#endif
