Program Listing for File peafowl.h

Return to documentation for file (include/peafowl/peafowl.h)

#ifndef PFWL_API_H
#define PFWL_API_H

#ifdef __cplusplus
extern "C" {
#endif

#include <peafowl/config.h>
#include <peafowl/utils.h>
#include <sys/types.h>
#include <net/ethernet.h>

typedef struct pfwl_flow_info_private pfwl_flow_info_private_t;

// clang-format off
typedef enum pfwl_status {
  PFWL_ERROR_L2_PARSING = -7,
  PFWL_ERROR_L3_PARSING = -6,
  PFWL_ERROR_L4_PARSING = -5,
  PFWL_ERROR_MAX_FLOWS = -4,
  PFWL_ERROR_IPV6_HDR_PARSING = -3,
  PFWL_ERROR_IPSEC_NOTSUPPORTED = -2,
  PFWL_ERROR_WRONG_IPVERSION = -1,
  PFWL_STATUS_OK = 0,
  PFWL_STATUS_IP_FRAGMENT,
  PFWL_STATUS_IP_DATA_REBUILT,
  PFWL_STATUS_TCP_OUT_OF_ORDER,
  PFWL_STATUS_TCP_CONNECTION_TERMINATED,
} pfwl_status_t;

// clang-format off
typedef enum pfwl_datalink_type {
  PFWL_PROTO_L2_EN10MB,
  PFWL_PROTO_L2_LINUX_SLL,
  PFWL_PROTO_L2_IEEE802_11_RADIO,
  PFWL_PROTO_L2_IEEE802_11,
  PFWL_PROTO_L2_IEEE802,
  PFWL_PROTO_L2_SLIP,
  PFWL_PROTO_L2_PPP,
  PFWL_PROTO_L2_FDDI,
  PFWL_PROTO_L2_RAW,
  PFWL_PROTO_L2_LOOP,
  PFWL_PROTO_L2_NULL,
  PFWL_PROTO_L2_NUM
} pfwl_protocol_l2_t;
// clang-format on

typedef enum {
  PFWL_PROTO_L3_IPV4 = 0x4,
  PFWL_PROTO_L3_IPV6 = 0x6,
  PFWL_PROTO_L3_NUM
} pfwl_protocol_l3_t;

typedef uint8_t pfwl_protocol_l4_t;

typedef enum {
  PFWL_PROTO_L7_DNS = 0,
  PFWL_PROTO_L7_MDNS,
  PFWL_PROTO_L7_DHCP,
  PFWL_PROTO_L7_DHCPv6,
  PFWL_PROTO_L7_NTP,
  PFWL_PROTO_L7_SIP,
  PFWL_PROTO_L7_RTP,
  PFWL_PROTO_L7_RTCP,
  PFWL_PROTO_L7_SSH,
  PFWL_PROTO_L7_SKYPE,
  PFWL_PROTO_L7_HTTP,
  PFWL_PROTO_L7_BGP,
  PFWL_PROTO_L7_SMTP,
  PFWL_PROTO_L7_POP3,
  PFWL_PROTO_L7_IMAP,
  PFWL_PROTO_L7_SSL,
  PFWL_PROTO_L7_HANGOUT,
  PFWL_PROTO_L7_WHATSAPP,
  PFWL_PROTO_L7_TELEGRAM,
  PFWL_PROTO_L7_DROPBOX,
  PFWL_PROTO_L7_SPOTIFY,
  PFWL_PROTO_L7_BITCOIN,
  PFWL_PROTO_L7_ETHEREUM,
  PFWL_PROTO_L7_ZCASH,
  PFWL_PROTO_L7_MONERO,
  PFWL_PROTO_L7_STRATUM,
  PFWL_PROTO_L7_JSON_RPC,
  PFWL_PROTO_L7_SSDP,
  PFWL_PROTO_L7_STUN,
  PFWL_PROTO_L7_QUIC,
  PFWL_PROTO_L7_QUIC5,
  PFWL_PROTO_L7_MQTT,
  PFWL_PROTO_L7_MYSQL,
  PFWL_PROTO_L7_VIBER,
  PFWL_PROTO_L7_KERBEROS,
  PFWL_PROTO_L7_TOR,
  PFWL_PROTO_L7_GIT,
  PFWL_PROTO_L7_NUM,
  PFWL_PROTO_L7_NOT_DETERMINED,
  PFWL_PROTO_L7_UNKNOWN,


} pfwl_protocol_l7_t;


typedef enum {
  PFWL_STAT_PACKETS                      ,
  PFWL_STAT_BYTES                        ,
  PFWL_STAT_TIMESTAMP_FIRST              ,
  PFWL_STAT_TIMESTAMP_LAST               ,
  PFWL_STAT_L4_TCP_RTT_SYN_ACK           ,
  PFWL_STAT_L4_TCP_COUNT_SYN             ,
  PFWL_STAT_L4_TCP_COUNT_FIN             ,
  PFWL_STAT_L4_TCP_COUNT_RST             ,
  PFWL_STAT_L4_TCP_COUNT_RETRANSMISSIONS ,
  PFWL_STAT_L4_TCP_COUNT_ZERO_WINDOW     ,
  PFWL_STAT_L4_TCP_WINDOW_SCALING        ,
  PFWL_STAT_L7_PACKETS                   ,
  PFWL_STAT_L7_BYTES                     ,
  PFWL_STAT_NUM                          ,
} pfwl_statistic_t;

// clang-format on

typedef enum {
  PFWL_TIMESTAMP_UNIT_MICROSECONDS,
  PFWL_TIMESTAMP_UNIT_MILLISECONDS,
  PFWL_TIMESTAMP_UNIT_SECONDS     ,
} pfwl_timestamp_unit_t;

typedef enum{
  PFWL_FLOWS_STRATEGY_NONE,
  PFWL_FLOWS_STRATEGY_SKIP,
  PFWL_FLOWS_STRATEGY_EVICT
}pfwl_flows_strategy_t;

typedef struct {
  const unsigned char *value;
  size_t length;
} pfwl_string_t;

typedef union {
  pfwl_string_t string;
  int64_t number;
} pfwl_basic_type_t;

typedef struct {
  pfwl_basic_type_t first;
  pfwl_basic_type_t second;
} pfwl_pair_t;

typedef struct {
  void *values;
  size_t length;
} pfwl_array_t;

typedef pfwl_array_t pfwl_mmap_t;

typedef struct pfwl_field {
  uint8_t present;
  union {
    pfwl_basic_type_t basic;
    pfwl_array_t array;
    pfwl_pair_t pair;
    pfwl_mmap_t mmap;
  };
} pfwl_field_t;

typedef enum {
  PFWL_FIELD_TYPE_STRING,
  PFWL_FIELD_TYPE_NUMBER,
  PFWL_FIELD_TYPE_ARRAY,
  PFWL_FIELD_TYPE_PAIR,
  PFWL_FIELD_TYPE_MMAP
} pfwl_field_type_t;

typedef enum {
  PFWL_DIRECTION_OUTBOUND,
  PFWL_DIRECTION_INBOUND
} pfwl_direction_t;

// clang-format off
//--PROTOFIELDENUMSTART | The following enum is autogenerated by generate_fields_enum.py. Please do not edit manually
typedef enum {
  PFWL_FIELDS_L7_SIP_REQUEST_URI,
  PFWL_FIELDS_L7_SIP_METHOD,
  PFWL_FIELDS_L7_SIP_CALLID,
  PFWL_FIELDS_L7_SIP_REASON,
  PFWL_FIELDS_L7_SIP_RTCPXR_CALLID,
  PFWL_FIELDS_L7_SIP_CSEQ,
  PFWL_FIELDS_L7_SIP_CSEQ_METHOD_STRING,
  PFWL_FIELDS_L7_SIP_VIA,
  PFWL_FIELDS_L7_SIP_CONTACT_URI,
  PFWL_FIELDS_L7_SIP_RURI_USER,
  PFWL_FIELDS_L7_SIP_RURI_DOMAIN,
  PFWL_FIELDS_L7_SIP_FROM_USER,
  PFWL_FIELDS_L7_SIP_FROM_DOMAIN,
  PFWL_FIELDS_L7_SIP_TO_USER,
  PFWL_FIELDS_L7_SIP_TO_DOMAIN,
  PFWL_FIELDS_L7_SIP_PAI_USER,
  PFWL_FIELDS_L7_SIP_PAI_DOMAIN,
  PFWL_FIELDS_L7_SIP_PID_URI,
  PFWL_FIELDS_L7_SIP_FROM_URI,
  PFWL_FIELDS_L7_SIP_TO_URI,
  PFWL_FIELDS_L7_SIP_RURI_URI,
  PFWL_FIELDS_L7_SIP_TO_TAG,
  PFWL_FIELDS_L7_SIP_FROM_TAG,
  PFWL_FIELDS_L7_DNS_NAME_SRV,
  PFWL_FIELDS_L7_DNS_NS_IP_1,
  PFWL_FIELDS_L7_DNS_NS_IP_2,
  PFWL_FIELDS_L7_DNS_AUTH_SRV,
  PFWL_FIELDS_L7_SSL_VERSION,
  PFWL_FIELDS_L7_SSL_VERSION_HANDSHAKE,
  PFWL_FIELDS_L7_SSL_HANDSHAKE_TYPE,
  PFWL_FIELDS_L7_SSL_CIPHER_SUITES,
  PFWL_FIELDS_L7_SSL_EXTENSIONS,
  PFWL_FIELDS_L7_SSL_ELLIPTIC_CURVES,
  PFWL_FIELDS_L7_SSL_ELLIPTIC_CURVES_POINT_FMTS,
  PFWL_FIELDS_L7_SSL_SNI,
  PFWL_FIELDS_L7_SSL_CERTIFICATE,
  PFWL_FIELDS_L7_SSL_JA3,
  PFWL_FIELDS_L7_HTTP_VERSION_MAJOR,
  PFWL_FIELDS_L7_HTTP_VERSION_MINOR,
  PFWL_FIELDS_L7_HTTP_METHOD,
  PFWL_FIELDS_L7_HTTP_STATUS_CODE,
  PFWL_FIELDS_L7_HTTP_MSG_TYPE,
  PFWL_FIELDS_L7_HTTP_BODY,
  PFWL_FIELDS_L7_HTTP_URL,
  PFWL_FIELDS_L7_HTTP_HEADERS,
  PFWL_FIELDS_L7_RTP_PTYPE,
  PFWL_FIELDS_L7_RTP_SEQNUM,
  PFWL_FIELDS_L7_RTP_TIMESTP,
  PFWL_FIELDS_L7_RTP_SSRC,
  PFWL_FIELDS_L7_RTCP_SENDER_ALL,
  PFWL_FIELDS_L7_RTCP_SENDER_SSRC,
  PFWL_FIELDS_L7_RTCP_SENDER_TIME_MSW,
  PFWL_FIELDS_L7_RTCP_SENDER_TIME_LSW,
  PFWL_FIELDS_L7_RTCP_SENDER_TIME_RTP,
  PFWL_FIELDS_L7_RTCP_SENDER_PKT_COUNT,
  PFWL_FIELDS_L7_RTCP_SENDER_OCT_COUNT,
  PFWL_FIELDS_L7_RTCP_SENDER_ID,
  PFWL_FIELDS_L7_RTCP_SENDER_FLCNPL,
  PFWL_FIELDS_L7_RTCP_SENDER_EXT_SEQN_RCV,
  PFWL_FIELDS_L7_RTCP_SENDER_INT_JITTER,
  PFWL_FIELDS_L7_RTCP_SENDER_LSR,
  PFWL_FIELDS_L7_RTCP_SENDER_DELAY_LSR,
  PFWL_FIELDS_L7_RTCP_RECEIVER_ALL,
  PFWL_FIELDS_L7_RTCP_RECEIVER_SSRC,
  PFWL_FIELDS_L7_RTCP_RECEIVER_ID,
  PFWL_FIELDS_L7_RTCP_RECEIVER_FLCNPL,
  PFWL_FIELDS_L7_RTCP_RECEIVER_EXT_SEQN_RCV,
  PFWL_FIELDS_L7_RTCP_RECEIVER_INT_JITTER,
  PFWL_FIELDS_L7_RTCP_RECEIVER_LSR,
  PFWL_FIELDS_L7_RTCP_RECEIVER_DELAY_LSR,
  PFWL_FIELDS_L7_RTCP_SDES_CSRC,
  PFWL_FIELDS_L7_RTCP_SDES_TEXT,
  PFWL_FIELDS_L7_JSON_RPC_FIRST,
  PFWL_FIELDS_L7_JSON_RPC_VERSION,
  PFWL_FIELDS_L7_JSON_RPC_MSG_TYPE,
  PFWL_FIELDS_L7_JSON_RPC_ID,
  PFWL_FIELDS_L7_JSON_RPC_METHOD,
  PFWL_FIELDS_L7_JSON_RPC_PARAMS,
  PFWL_FIELDS_L7_JSON_RPC_RESULT,
  PFWL_FIELDS_L7_JSON_RPC_ERROR,
  PFWL_FIELDS_L7_JSON_RPC_LAST,
  PFWL_FIELDS_L7_QUIC_VERSION,
  PFWL_FIELDS_L7_QUIC_SNI,
  PFWL_FIELDS_L7_QUIC_UAID,
  PFWL_FIELDS_L7_QUIC_JA3,
  PFWL_FIELDS_L7_STUN_MAPPED_ADDRESS,
  PFWL_FIELDS_L7_STUN_MAPPED_ADDRESS_PORT,
  PFWL_FIELDS_L7_NUM,
}pfwl_field_id_t;

//--PROTOFIELDENUMEND

typedef union pfwl_ip_addr {
  uint32_t ipv4;
  struct in6_addr ipv6;
} pfwl_ip_addr_t;

#define PFWL_MAX_L7_SUBPROTO_DEPTH 10
#define PFWL_TAGS_MAX 128


typedef struct pfwl_flow_info {
  uint64_t id;
  uint32_t id_hash;
  uint16_t thread_id;
  pfwl_ip_addr_t addr_src;
  pfwl_ip_addr_t addr_dst;
  uint16_t port_src;
  uint16_t port_dst;
  uint64_t num_packets[2];
  uint64_t num_bytes[2];
  uint64_t num_packets_l7[2];
  uint64_t
      num_bytes_l7[2];
  uint32_t
      timestamp_first[2];
  uint32_t
      timestamp_last[2];

  pfwl_protocol_l2_t protocol_l2;
  pfwl_protocol_l3_t protocol_l3;
  pfwl_protocol_l4_t protocol_l4;
  double statistics[PFWL_STAT_NUM][2];
  double splt_lengths[PFWL_MAX_SPLT_LENGTH][2];
  double splt_times[PFWL_MAX_SPLT_LENGTH][2];
  uint8_t splt_stored_records[2];
  pfwl_protocol_l7_t protocols_l7[PFWL_MAX_L7_SUBPROTO_DEPTH];
  uint8_t protocols_l7_num;
  void **udata;

} pfwl_flow_info_t;

typedef struct pfwl_dissection_info_l2 {
  size_t length;
  pfwl_protocol_l2_t protocol;
  uint8_t mac_src[ETH_ALEN];
  uint8_t mac_dst[ETH_ALEN];
}pfwl_dissection_info_l2_t;

typedef struct pfwl_dissection_info_l3 {
  size_t length;
  size_t payload_length;
  pfwl_ip_addr_t addr_src;
  pfwl_ip_addr_t addr_dst;
  const unsigned char *refrag_pkt;
  size_t refrag_pkt_len;
  pfwl_protocol_l3_t protocol;
}pfwl_dissection_info_l3_t;

typedef struct pfwl_dissection_info_l4 {
  size_t length;
  size_t payload_length;
  uint16_t port_src;
  uint16_t port_dst;
  pfwl_direction_t direction;
  const unsigned char *resegmented_pkt;
  size_t resegmented_pkt_len;
  pfwl_protocol_l4_t protocol;
}pfwl_dissection_info_l4_t;

typedef struct pfwl_dissection_info_l7 {
  pfwl_protocol_l7_t protocol;
  pfwl_protocol_l7_t protocols[PFWL_MAX_L7_SUBPROTO_DEPTH];
  uint8_t protocols_num;
  pfwl_field_t protocol_fields[PFWL_FIELDS_L7_NUM];
  const char* tags[PFWL_TAGS_MAX];
  uint16_t tags_num;
}pfwl_dissection_info_l7_t;

typedef struct pfwl_dissection_info {
  pfwl_dissection_info_l2_t l2;
  pfwl_dissection_info_l3_t l3;
  pfwl_dissection_info_l4_t l4;
  pfwl_dissection_info_l7_t l7;
  pfwl_flow_info_t flow_info;
} pfwl_dissection_info_t;

// clang-format on

typedef void(pfwl_flow_cleaner_callback_t)(void *flow_udata);

typedef void(pfwl_flow_termination_callback_t)(pfwl_flow_info_t* flow_info);

typedef struct pfwl_state pfwl_state_t;

typedef enum {
  PFWL_DISSECTOR_ACCURACY_LOW,
  PFWL_DISSECTOR_ACCURACY_MEDIUM,
  PFWL_DISSECTOR_ACCURACY_HIGH,
} pfwl_dissector_accuracy_t;

pfwl_state_t *pfwl_init(void);

void pfwl_terminate(pfwl_state_t *state);

uint8_t pfwl_set_expected_flows(pfwl_state_t *state, uint32_t flows,
                                pfwl_flows_strategy_t strategy);

uint8_t pfwl_set_max_trials(pfwl_state_t *state, uint16_t max_trials);

uint8_t pfwl_defragmentation_enable_ipv4(pfwl_state_t *state,
                                         uint16_t table_size);

uint8_t pfwl_defragmentation_enable_ipv6(pfwl_state_t *state,
                                         uint16_t table_size);

uint8_t pfwl_defragmentation_set_per_host_memory_limit_ipv4(
    pfwl_state_t *state, uint32_t per_host_memory_limit);

uint8_t pfwl_defragmentation_set_per_host_memory_limit_ipv6(
    pfwl_state_t *state, uint32_t per_host_memory_limit);

uint8_t
pfwl_defragmentation_set_total_memory_limit_ipv4(pfwl_state_t *state,
                                                 uint32_t total_memory_limit);

uint8_t
pfwl_defragmentation_set_total_memory_limit_ipv6(pfwl_state_t *state,
                                                 uint32_t total_memory_limit);

uint8_t
pfwl_defragmentation_set_reassembly_timeout_ipv4(pfwl_state_t *state,
                                                 uint8_t timeout_seconds);

uint8_t
pfwl_defragmentation_set_reassembly_timeout_ipv6(pfwl_state_t *state,
                                                 uint8_t timeout_seconds);

uint8_t pfwl_defragmentation_disable_ipv4(pfwl_state_t *state);

uint8_t pfwl_defragmentation_disable_ipv6(pfwl_state_t *state);

uint8_t pfwl_tcp_reordering_enable(pfwl_state_t *state);

uint8_t pfwl_tcp_reordering_disable(pfwl_state_t *state);

uint8_t pfwl_protocol_l7_enable(pfwl_state_t *state,
                                pfwl_protocol_l7_t protocol);

uint8_t pfwl_protocol_l7_disable(pfwl_state_t *state,
                                 pfwl_protocol_l7_t protocol);

uint8_t pfwl_protocol_l7_enable_all(pfwl_state_t *state);

uint8_t pfwl_protocol_l7_disable_all(pfwl_state_t *state);

uint8_t pfwl_set_timestamp_unit(pfwl_state_t *state, pfwl_timestamp_unit_t unit);

pfwl_status_t pfwl_dissect_from_L2(pfwl_state_t *state,
                                   const unsigned char *pkt, size_t length,
                                   double timestamp,
                                   pfwl_protocol_l2_t datalink_type,
                                   pfwl_dissection_info_t *dissection_info);

pfwl_status_t pfwl_dissect_from_L3(pfwl_state_t *state,
                                   const unsigned char *pkt, size_t length,
                                   double timestamp,
                                   pfwl_dissection_info_t *dissection_info);

pfwl_status_t pfwl_dissect_from_L4(pfwl_state_t *state,
                                   const unsigned char *pkt, size_t length,
                                   double timestamp,
                                   pfwl_dissection_info_t *dissection_info);

pfwl_status_t pfwl_dissect_L2(const unsigned char *packet,
                              pfwl_protocol_l2_t datalink_type,
                              pfwl_dissection_info_t *dissection_info);

pfwl_status_t pfwl_dissect_L3(pfwl_state_t *state, const unsigned char *pkt,
                              size_t length, double timestamp,
                              pfwl_dissection_info_t *dissection_info);

pfwl_status_t pfwl_dissect_L4(pfwl_state_t *state, const unsigned char *pkt,
                              size_t length, double timestamp,
                              pfwl_dissection_info_t *dissection_info,
                              pfwl_flow_info_private_t **flow_info_private);

pfwl_status_t pfwl_dissect_L7(pfwl_state_t *state, const unsigned char *pkt,
                              size_t length,
                              pfwl_dissection_info_t *dissection_info,
                              pfwl_flow_info_private_t *flow_info_private);

pfwl_flow_info_private_t* pfwl_create_flow_info_private(pfwl_state_t* state,
                                                        const pfwl_dissection_info_t *dissection_info);

void pfwl_destroy_flow_info_private(pfwl_flow_info_private_t* info);

void pfwl_init_flow_info(pfwl_state_t *state,
                         pfwl_flow_info_private_t *flow_info_private);

pfwl_protocol_l7_t
pfwl_guess_protocol(pfwl_dissection_info_t identification_info);

const char *pfwl_get_status_msg(pfwl_status_t status_code);

const char *pfwl_get_L2_protocol_name(pfwl_protocol_l2_t protocol);

pfwl_protocol_l2_t pfwl_get_L2_protocol_id(const char *const name);

const char **const pfwl_get_L2_protocols_names();

const char *pfwl_get_L3_protocol_name(pfwl_protocol_l3_t protocol);

pfwl_protocol_l3_t pfwl_get_L3_protocol_id(const char *const name);

const char **const pfwl_get_L3_protocols_names();

const char *pfwl_get_L4_protocol_name(pfwl_protocol_l4_t protocol);

pfwl_protocol_l4_t pfwl_get_L4_protocol_id(const char *const name);

const char **const pfwl_get_L4_protocols_names();

const char *pfwl_get_L7_protocol_name(pfwl_protocol_l7_t protocol);

pfwl_protocol_l7_t pfwl_get_L7_protocol_id(const char *const name);

const char **const pfwl_get_L7_protocols_names();

const char* pfwl_get_L7_field_name(pfwl_field_id_t field);

pfwl_field_id_t pfwl_get_L7_field_id(pfwl_protocol_l7_t protocol, const char* field_name);

pfwl_protocol_l7_t pfwl_get_L7_field_protocol(pfwl_field_id_t field);

uint8_t pfwl_set_flow_cleaner_callback(pfwl_state_t *state,
                                       pfwl_flow_cleaner_callback_t *cleaner);

uint8_t pfwl_set_flow_termination_callback(pfwl_state_t *state,
                                           pfwl_flow_termination_callback_t *cleaner);

uint8_t pfwl_statistic_add(pfwl_state_t* state, pfwl_statistic_t stat);

uint8_t pfwl_statistic_remove(pfwl_state_t* state, pfwl_statistic_t stat);

uint8_t pfwl_field_add_L7(pfwl_state_t *state, pfwl_field_id_t field);

uint8_t pfwl_field_remove_L7(pfwl_state_t *state, pfwl_field_id_t field);

uint8_t pfwl_set_protocol_accuracy_L7(pfwl_state_t *state,
                                      pfwl_protocol_l7_t protocol,
                                      pfwl_dissector_accuracy_t accuracy);

pfwl_field_type_t pfwl_get_L7_field_type(pfwl_field_id_t field);

uint8_t pfwl_field_string_get(pfwl_field_t *fields, pfwl_field_id_t id,
                              pfwl_string_t *string);

uint8_t pfwl_field_number_get(pfwl_field_t *fields, pfwl_field_id_t id,
                              int64_t *number);

uint8_t pfwl_field_array_length(pfwl_field_t *fields, pfwl_field_id_t id,
                                size_t *length);

uint8_t pfwl_field_array_get_pair(pfwl_field_t *fields, pfwl_field_id_t id,
                                  size_t position, pfwl_pair_t *pair);

uint8_t pfwl_http_get_header(pfwl_dissection_info_t *dissection_info,
                             const char *header_name,
                             pfwl_string_t *header_value);

uint8_t pfwl_has_protocol_L7(pfwl_dissection_info_t* dissection_info, pfwl_protocol_l7_t protocol);

pfwl_protocol_l2_t pfwl_convert_pcap_dlt(int dlt);

typedef enum{
  PFWL_FIELD_MATCHING_PREFIX,
  PFWL_FIELD_MATCHING_EXACT,
  PFWL_FIELD_MATCHING_SUFFIX,
  PFWL_FIELD_MATCHING_ERROR
}pfwl_field_matching_t;

int pfwl_field_tags_load_L7(pfwl_state_t* state, pfwl_field_id_t field, const char* tags_file);

void pfwl_field_string_tags_add_L7(pfwl_state_t* state, pfwl_field_id_t field, const char* value, pfwl_field_matching_t matchingType, const char* tag);

void pfwl_field_mmap_tags_add_L7(pfwl_state_t* state, pfwl_field_id_t field, const char* key, const char* value, pfwl_field_matching_t matchingType, const char* tag);

void pfwl_field_tags_unload_L7(pfwl_state_t* state, pfwl_field_id_t field);

pfwl_state_t *pfwl_init_stateful_num_partitions(uint32_t expected_flows,
                                                uint8_t strict,
                                                uint16_t num_table_partitions);

pfwl_status_t mc_pfwl_parse_L3_header(pfwl_state_t *state,
                                      const unsigned char *p_pkt,
                                      size_t p_length, double current_time,
                                      int tid,
                                      pfwl_dissection_info_t *dissection_info);

pfwl_status_t
mc_pfwl_parse_L4_header(pfwl_state_t *state, const unsigned char *p_pkt,
                        size_t p_length, double timestamp, int tid,
                        pfwl_dissection_info_t *dissection_info,
                        pfwl_flow_info_private_t **flow_info_private);

typedef struct pfwl_l7_skipping_info pfwl_l7_skipping_info_t;

typedef struct pfwl_state {
  /********************************************************************/
  /********************************************************************/
  void *flow_table;

  void *protocols_internal_state[PFWL_PROTO_L7_NUM]; // For each protocol, an
                                                     // internal state to be
                                                     // shared among flows

  /********************************************************************/
  /********************************************************************/
  char protocols_to_inspect[BITNSLOTS(PFWL_PROTO_L7_NUM)];

  pfwl_protocol_l7_t active_protocols[2]; // 0 for TCP, 1 for UDP

  uint16_t max_trials;

  pfwl_timestamp_unit_t ts_unit;

  uint8_t fields_to_extract[PFWL_FIELDS_L7_NUM];

  uint8_t stats_to_compute[PFWL_STAT_NUM];

  uint8_t fields_to_extract_num[PFWL_PROTO_L7_NUM];

  uint8_t fields_support[PFWL_FIELDS_L7_NUM];
  uint8_t fields_support_num[PFWL_PROTO_L7_NUM];

  pfwl_protocol_l7_t protocol_dependencies[PFWL_PROTO_L7_NUM][PFWL_PROTO_L7_NUM + 1];

  uint8_t tcp_reordering_enabled : 1;

  pfwl_l7_skipping_info_t *l7_skip;

  pfwl_dissector_accuracy_t inspectors_accuracy[PFWL_PROTO_L7_NUM];

  void* tags_matchers[PFWL_FIELDS_L7_NUM];
  size_t tags_matchers_num;

  size_t next_flow_id;

  char scratchpad[1024*1024];
  size_t scratchpad_next_byte;

  /********************************************************************/
  /********************************************************************/
  void *ipv4_frag_state;
  void *ipv6_frag_state;
} pfwl_state_t;

// Bindings support structures
// To be DEPRECATED
typedef struct pfwl_dissection_info_for_bindings {
  size_t l2_length;
  pfwl_protocol_l2_t l2_protocol;
  size_t l3_length;
  size_t l3_payload_length;
  pfwl_ip_addr_t l3_addr_src;
  pfwl_ip_addr_t l3_addr_dst;
  const unsigned char *l3_refrag_pkt;
  size_t l3_refrag_pkt_len;
  pfwl_protocol_l3_t l3_protocol;
  size_t l4_length;
  size_t l4_payload_length;
  uint16_t l4_port_src;
  uint16_t l4_port_dst;
  uint8_t l4_direction;
  const unsigned char *l4_resegmented_pkt;
  size_t l4_resegmented_pkt_len;
  pfwl_protocol_l4_t l4_protocol;
  pfwl_protocol_l7_t l7_protocol;
  pfwl_field_t l7_protocol_fields[PFWL_FIELDS_L7_NUM];
  uint64_t flow_info_num_packets[2];
  uint64_t flow_info_num_bytes[2];
  uint64_t flow_info_num_packets_l7[2];
  uint64_t flow_info_num_bytes_l7[2];
  void **flow_info_udata;
  uint32_t flow_info_timestamp_first[2];
  uint32_t flow_info_timestamp_last[2];
} pfwl_dissection_info_for_bindings_t;



#ifdef __cplusplus
}
#endif

#endif