blob: 49cec5831c1550c25f90a599370a2ac43bd072bc [file] [log] [blame]
/*
**************************************************************************
* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
**************************************************************************
*/
struct ecm_tracker_instance;
/*
* Data tracking data limits - system global and per-connection - defaults.
*/
#define ECM_TRACKER_GLOBAL_DATA_LIMIT_DEFAULT (1024 * 1024 * 8)
#define ECM_TRACKER_GLOBAL_DATA_BUFFER_LIMIT_DEFAULT (1024 * 1024 * 64)
#define ECM_TRACKER_CONNECTION_TRACKING_LIMIT_DEFAULT (1024 * 1024)
#define ECM_TRACKER_CONNECTION_TRACKING_LIMIT_MAX ECM_TRACKER_GLOBAL_DATA_LIMIT_DEFAULT
enum ecm_tracker_sender_types {
ECM_TRACKER_SENDER_TYPE_SRC = 0, /* Sender of tracked data is the source of the connection (who established the connection) */
ECM_TRACKER_SENDER_TYPE_DEST = 1, /* Sender of tracked data is the destination of the connection (to whom connection was established) */
ECM_TRACKER_SENDER_MAX, /* MUST BE LAST */
};
typedef enum ecm_tracker_sender_types ecm_tracker_sender_type_t;
/*
* enum ecm_tracker_sender_states
* Notional states of senders of a tracker
*
* Order is important here - don't change them as logic depends on their numerical value.
*/
enum ecm_tracker_sender_states {
ECM_TRACKER_SENDER_STATE_UNKNOWN = 0, /* Endpoint has not sent any packets yet */
ECM_TRACKER_SENDER_STATE_ESTABLISHING, /* Endpoint has not yet given any indication it is established */
ECM_TRACKER_SENDER_STATE_ESTABLISHED, /* Endpoint has indicated that it is established */
ECM_TRACKER_SENDER_STATE_CLOSING, /* Endpoint has indicated that it wants to close down its side of the connection */
ECM_TRACKER_SENDER_STATE_CLOSED, /* Endpoint has closed, connection remains to service any late packets */
ECM_TRACKER_SENDER_STATE_FAULT, /* Endpoint experienced a fault */
ECM_TRACKER_SENDER_STATE_MAX, /* MUST BE LAST */
};
typedef enum ecm_tracker_sender_states ecm_tracker_sender_state_t;
/*
* ecm_tracker_sender_state_to_string[]
* Convert a sender state to a string
*/
const char *
ecm_tracker_sender_state_to_string(enum ecm_tracker_sender_states);
/*
* enum ecm_tracker_connection_states
* Notional states of connection being monitored by the tracker
*
* Order is important here - don't change them as logic depends on their numerical value.
*/
enum ecm_tracker_connection_states {
ECM_TRACKER_CONNECTION_STATE_ESTABLISHING = 0, /* Not yet given any indication it is established */
ECM_TRACKER_CONNECTION_STATE_ESTABLISHED, /* It is established */
ECM_TRACKER_CONNECTION_STATE_CLOSING, /* Connection has begun process of closing */
ECM_TRACKER_CONNECTION_STATE_CLOSED, /* Has closed, connection remains to service any late packets */
ECM_TRACKER_CONNECTION_STATE_FAULT, /* Experienced a fault */
ECM_TRACKER_CONNECTION_STATE_MAX, /* MUST BE LAST */
};
typedef enum ecm_tracker_connection_states ecm_tracker_connection_state_t;
/*
* ecm_tracker_connection_state_to_string
* Convert a connection state to a string
*/
const char *ecm_tracker_connection_state_to_string(enum ecm_tracker_connection_states);
/*
* enum ecm_tracker_ip_protocol_types
* A list of protocol types that can be recorded in the ecm_ip_header
*
* This is especially useful for IPv6 where the ip header can contain many sub headers.
* But it is also useful for IPv4 where you might have IP following a GRE header, for example.
* An ECM IP header may record only ONE of each type of header, if more are found the header is considered invalid.
*
* These constants are used to index into the ecm_tracker_ip_header.headers[]
*/
enum ecm_tracker_ip_protocol_types {
ECM_TRACKER_IP_PROTOCOL_TYPE_UNKNOWN, /* A protocol that is unrecognised */
ECM_TRACKER_IP_PROTOCOL_TYPE_ICMP,
ECM_TRACKER_IP_PROTOCOL_TYPE_UDP,
ECM_TRACKER_IP_PROTOCOL_TYPE_TCP,
ECM_TRACKER_IP_PROTOCOL_TYPE_GRE,
#ifdef ECM_IPV6_ENABLE
ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_ROUTING,
ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_FRAGMENT,
ECM_TRACKER_IP_PROTOCOL_TYPE_AH,
ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_ICMP,
ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_DO,
ECM_TRACKER_IP_PROTOCOL_TYPE_IPV6_HBH, /* IPv6 hop-by-hop header */
#endif
ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT /* Must be last, do not use */
};
typedef enum ecm_tracker_ip_protocol_types ecm_tracker_ip_protocol_type_t;
/*
* struct ecm_tracker_ip_protocol_header
* Records a protocol header as stored within an IP datagram
*/
struct ecm_tracker_ip_protocol_header {
uint8_t protocol_number; /* IP protocol number */
uint16_t header_size; /* Size of the protocol header */
uint16_t size; /* Size of the header_size + its payload */
uint16_t offset; /* Offset from the start of the skb where this header is located */
};
/*
* struct ecm_tracker_ip_header
* An IP header in the ECM can deal with V4 and V6 headers.
*
* WARNING: An ecm_ip_header is ONLY VALID while the skb from which it was initialised remains untouched.
*/
struct ecm_tracker_ip_header {
/*
* h is a union of IP version headers.
* These are ONLY used as buffers where skb_header_pointer() needs them to perform a skb_copy_bits() operation.
* WARNING: You should NOT rely on the content of these structures because skb_header_pointer() may not have used them!
* Use the actual fields below instead.
*/
union {
struct iphdr v4_hdr;
#ifdef ECM_IPV6_ENABLE
struct ipv6hdr v6_hdr;
#endif
} h;
struct sk_buff *skb; /* COPY of POINTER to the skb this header relates to. This ecm_tracker_ip_header is ONLY VALID for as long as the skb it relates to remains UNTOUCHED */
bool is_v4; /* True when v4, else v6 */
ip_addr_t src_addr; /* ECM ip address equivalent */
ip_addr_t dest_addr; /* ECM ip address equivalent */
int protocol; /* The upper layer transport protocol */
bool fragmented; /* True when fragmented */
uint8_t ds; /* DS field from packet */
uint8_t ttl; /* v4 TTL or v6 hop limit */
uint32_t ip_header_length; /* Length of the IP header plus any variable sized intrinsically attached options */
uint32_t total_length; /* total length of IP header including all extensions and payload. For v4 this is total_len, for v6 this is payload_len + size of the IP 6 header */
uint32_t payload_length; /* total_length - ip_header_length */
struct ecm_tracker_ip_protocol_header headers[ECM_TRACKER_IP_PROTOCOL_TYPE_COUNT];
/* Use one of the ECM_TRACKER_IP_PROTOCOL_TYPE_XYZ constants to index into this to locate the header you want to inspect. If the size is zero then the header was not found. */
};
#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE
typedef int32_t (*ecm_tracker_datagram_count_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender);
/* Return number of available datagrams sent by the sender */
typedef void (*ecm_tracker_datagram_discard_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t n);
/* Discard n number of datagrams at the head of the datagram list that were sent by the sender */
typedef int32_t (*ecm_tracker_datagram_size_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t i);
/* Return size in bytes of datagram at index i that was sent by the sender */
typedef int (*ecm_tracker_datagram_read_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, int32_t i, int32_t offset, int32_t size, void *buffer);
/* Read size bytes from datagram at index i into the buffer */
typedef bool (*ecm_tracker_datagram_add_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, struct sk_buff *skb);
/* Add (append) the datagram into the tracker */
typedef void (*ecm_tracker_discard_all_method_t)(struct ecm_tracker_instance *ti);
/* Discard all tracked data */
typedef int32_t (*ecm_tracker_data_total_get_method_t)(struct ecm_tracker_instance *ti);
/* Return number of bytes of tracked data in total */
typedef int32_t (*ecm_tracker_data_limit_get_method_t)(struct ecm_tracker_instance *ti);
/* Return the limit on the number of bytes we can track */
typedef void (*ecm_tracker_data_limit_set_method_t)(struct ecm_tracker_instance *ti, int32_t data_limit);
/* Set the limit on the number of bytes we can track */
#endif
typedef void (*ecm_tracker_ref_method_t)(struct ecm_tracker_instance *ti);
typedef int (*ecm_tracker_deref_method_t)(struct ecm_tracker_instance *ti);
typedef void (*ecm_tracker_state_update_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_type_t sender, struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb);
/* Update state of the sender */
typedef void (*ecm_tracker_state_get_method_t)(struct ecm_tracker_instance *ti, ecm_tracker_sender_state_t *src_state, ecm_tracker_sender_state_t *dest_state, ecm_tracker_connection_state_t *state, ecm_db_timer_group_t *tg);
/* State of the connection */
#ifdef ECM_STATE_OUTPUT_ENABLE
typedef int (*ecm_tracker_state_get_callback_t)(struct ecm_tracker_instance *ti, struct ecm_state_file_instance *sfi);
/*
* Get state output.
* Returns zero on success.
*/
#endif
/*
* struct ecm_tracker_instance
* Base class of all trackers
*
* ALL trackers must implement these features in addition to their own.
* ALL trackers must be castable to a type of this, i.e. this structure must be the first element of their own data type.
*/
struct ecm_tracker_instance {
#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE
ecm_tracker_data_total_get_method_t data_total_get;
ecm_tracker_data_limit_get_method_t data_limit_get;
ecm_tracker_data_limit_set_method_t data_limit_set;
ecm_tracker_datagram_count_get_method_t datagram_count_get;
ecm_tracker_datagram_discard_method_t datagram_discard;
ecm_tracker_datagram_size_get_method_t datagram_size_get;
ecm_tracker_datagram_read_method_t datagram_read;
ecm_tracker_datagram_add_method_t datagram_add;
ecm_tracker_discard_all_method_t discard_all;
#endif
ecm_tracker_state_update_method_t state_update;
ecm_tracker_state_get_method_t state_get;
#ifdef ECM_STATE_OUTPUT_ENABLE
ecm_tracker_state_get_callback_t state_text_get; /* Return text containing its state */
#endif
ecm_tracker_ref_method_t ref;
ecm_tracker_deref_method_t deref;
};
bool ecm_tracker_ip_check_header_and_read(struct ecm_tracker_ip_header *ip_hdr, struct sk_buff *skb);
#ifdef ECM_TRACKER_DPI_SUPPORT_ENABLE
uint32_t ecm_tracker_data_limit_get(void);
void ecm_tracker_data_limit_set(uint32_t limit);
uint32_t ecm_tracker_data_total_get(void);
uint32_t ecm_tracker_data_buffer_total_get(void);
bool ecm_tracker_data_total_increase(uint32_t n, uint32_t data_bufer_size);
void ecm_tracker_data_total_decrease(uint32_t n, uint32_t data_bufer_size);
#endif