From b4c3a23c884c24f4e5d941fb928cf49561a9cdf9 Mon Sep 17 00:00:00 2001 From: "/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org" Date: Tue, 19 Dec 2006 17:41:53 +0000 Subject: Introduce the new libnetfilter_conntrack API, features: - object oriented infrastructure - extensible and configurable output (XML) - low level functions to interact with netlink details - fairly documented Still backward compatible. --- include/Makefile.am | 2 +- include/internal.h | 154 +++++++++++++++ .../libnetfilter_conntrack.h | 214 +++++++++++++++++++++ .../libnetfilter_conntrack_tcp.h | 15 ++ .../linux_nfnetlink_conntrack.h | 4 +- 5 files changed, 387 insertions(+), 2 deletions(-) create mode 100644 include/internal.h (limited to 'include') diff --git a/include/Makefile.am b/include/Makefile.am index f1aa6b8..7113c9c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,4 +1,4 @@ SUBDIRS = libnetfilter_conntrack -noinst_HEADERS = linux_list.h +noinst_HEADERS = linux_list.h internal.h diff --git a/include/internal.h b/include/internal.h new file mode 100644 index 0000000..2ca9b0c --- /dev/null +++ b/include/internal.h @@ -0,0 +1,154 @@ +/* + * (C) 2006 by Pablo Neira Ayuso + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * WARNING: Do *NOT* ever include this file, only for internal use! + * Use the set/get API in order to set/get the conntrack attributes + */ + +#ifndef __LIBNETFILTER_CONNTRACK_INTERNAL__ +#define __LIBNETFILTER_CONNTRACK_INTERNAL__ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +struct nfct_handle; + +typedef void (*set_attr)(struct nf_conntrack *ct, const void *value); +typedef const void *(*get_attr)(const struct nf_conntrack *ct); + +extern set_attr set_attr_array[]; +extern get_attr get_attr_array[]; + +typedef int (*nfct_handler)(struct nfct_handle *cth, struct nlmsghdr *nlh, + void *arg); + +struct nfct_handle { + struct nfnl_handle *nfnlh; + struct nfnl_subsys_handle *nfnlssh_ct; + struct nfnl_subsys_handle *nfnlssh_exp; + nfct_callback callback; /* user callback */ + void *callback_data; /* user data for callback */ + nfct_handler handler; /* netlink handler */ + + /* callback handler for the new API */ + struct nfnl_callback nfnl_cb; + int(*cb)(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, + void *data); +}; + +union __nfct_l4 { + /* Add other protocols here. */ + u_int16_t all; + struct { + u_int16_t port; + } tcp; + struct { + u_int16_t port; + } udp; + struct { + u_int8_t type, code; + u_int16_t id; + } icmp; + struct { + u_int16_t port; + } sctp; +}; + +union __nfct_address { + u_int32_t v4; + struct in6_addr v6; +}; + +struct __nfct_tuple { + union __nfct_address src; + union __nfct_address dst; + + u_int8_t l3protonum; + u_int8_t protonum; + union __nfct_l4 l4src; + union __nfct_l4 l4dst; +}; + +union __nfct_protoinfo { + struct { + u_int8_t state; + } tcp; +}; + +struct __nfct_counters { + u_int64_t packets; + u_int64_t bytes; +}; + +struct __nfct_nat { + u_int32_t min_ip, max_ip; + union __nfct_l4 l4min, l4max; +}; + +#define __DIR_ORIG 0 +#define __DIR_REPL 1 +#define __DIR_MAX __DIR_REPL+1 + +struct nf_conntrack { + struct __nfct_tuple tuple[__DIR_MAX]; + + u_int32_t timeout; + u_int32_t mark; + u_int32_t status; + u_int32_t use; + u_int32_t id; + + union __nfct_protoinfo protoinfo; + struct __nfct_counters counters[__DIR_MAX]; + struct __nfct_nat snat; + struct __nfct_nat dnat; + + u_int32_t set[2]; +}; + +/* container used to pass data to nfnl callbacks */ +struct __data_container { + struct nfct_handle *h; + enum nf_conntrack_msg_type type; + void *data; +}; + +static inline void set_bit(int nr, u_int32_t *addr) +{ + addr[nr >> 5] |= (1UL << (nr & 31)); +} + +static inline void unset_bit(int nr, u_int32_t *addr) +{ + addr[nr >> 5] &= ~(1UL << (nr & 31)); +} + +static inline int test_bit(int nr, const u_int32_t *addr) +{ + return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; +} + +int __build_conntrack(struct nfnl_subsys_handle *ssh, struct nfnlhdr *req, size_t size, u_int16_t type, u_int16_t flags, const struct nf_conntrack *ct); +int __parse_message_type(const struct nlmsghdr *nlh); +void __parse_conntrack(const struct nlmsghdr *nlh, const struct nfattr *cda[], struct nf_conntrack *ct); +int __snprintf_conntrack(char *buf, unsigned int len, const struct nf_conntrack *ct, unsigned int type, unsigned int msg_output, unsigned int flags); + + +int __callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data); + +int __setobjopt(struct nf_conntrack *ct, unsigned int option); +int __getobjopt(const struct nf_conntrack *ct, unsigned int option); + +#endif diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h index e9af624..9e7dd37 100644 --- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h @@ -332,6 +332,220 @@ extern int nfct_sprintf_expect_id(char *buf, struct nfct_expect *exp); extern void nfct_build_tuple(struct nfnlhdr *req, int size, struct nfct_tuple *t, int type); +/* + * NEW libnetfilter_conntrack API + */ + +/* high level API */ + +#include + +/* conntrack object */ +struct nf_conntrack; + +/* conntrack attributes */ +enum nf_conntrack_attr { + ATTR_ORIG_IPV4_SRC = 0, /* u32 bits */ + ATTR_ORIG_IPV4_DST, /* u32 bits */ + ATTR_REPL_IPV4_SRC, /* u32 bits */ + ATTR_REPL_IPV4_DST, /* u32 bits */ + ATTR_ORIG_IPV6_SRC = 4, /* u128 bits */ + ATTR_ORIG_IPV6_DST, /* u128 bits */ + ATTR_REPL_IPV6_SRC, /* u128 bits */ + ATTR_REPL_IPV6_DST, /* u128 bits */ + ATTR_ORIG_PORT_SRC = 8, /* u16 bits */ + ATTR_ORIG_PORT_DST, /* u16 bits */ + ATTR_REPL_PORT_SRC, /* u16 bits */ + ATTR_REPL_PORT_DST, /* u16 bits */ + ATTR_ICMP_TYPE = 12, /* u8 bits */ + ATTR_ICMP_CODE, /* u8 bits */ + ATTR_ICMP_ID, /* u8 bits */ + ATTR_ORIG_L3PROTO, /* u8 bits */ + ATTR_REPL_L3PROTO = 16, /* u8 bits */ + ATTR_ORIG_L4PROTO, /* u8 bits */ + ATTR_REPL_L4PROTO, /* u8 bits */ + ATTR_TCP_STATE, /* u8 bits */ + ATTR_SNAT_IPV4 = 20, /* u32 bits */ + ATTR_DNAT_IPV4, /* u32 bits */ + ATTR_SNAT_PORT, /* u16 bits */ + ATTR_DNAT_PORT, /* u16 bits */ + ATTR_TIMEOUT = 24, /* u32 bits */ + ATTR_MARK, /* u32 bits */ + ATTR_ORIG_COUNTER_PACKETS, /* u32 bits */ + ATTR_REPL_COUNTER_PACKETS, /* u32 bits */ + ATTR_ORIG_COUNTER_BYTES = 28, /* u32 bits */ + ATTR_REPL_COUNTER_BYTES, /* u32 bits */ + ATTR_USE, /* u32 bits */ + ATTR_ID, /* u32 bits */ + ATTR_STATUS = 32, /* u32 bits */ + ATTR_MAX +}; + +/* message type */ +enum nf_conntrack_msg_type { + NFCT_T_UNKNOWN = 0, + + NFCT_T_NEW_BIT = 0, + NFCT_T_NEW = (1 << NFCT_T_NEW_BIT), + + NFCT_T_UPDATE_BIT = 1, + NFCT_T_UPDATE = (1 << NFCT_T_UPDATE_BIT), + + NFCT_T_DESTROY_BIT = 2, + NFCT_T_DESTROY = (1 << NFCT_T_DESTROY_BIT), + + NFCT_T_ALL = NFCT_T_NEW | NFCT_T_UPDATE | NFCT_T_DESTROY, + + NFCT_T_ERROR_BIT = 31, + NFCT_T_ERROR = (1 << NFCT_T_ERROR_BIT), +}; + +/* constructor / destructor */ +extern struct nf_conntrack *nfct_new(void); +extern void nfct_destroy(struct nf_conntrack *ct); + +/* clone */ +struct nf_conntrack *nfct_clone(const struct nf_conntrack *ct); + +/* object size */ +extern size_t nfct_sizeof(const struct nf_conntrack *ct); + +/* set option */ +enum { + NFCT_SOPT_UNDO_SNAT, + NFCT_SOPT_UNDO_DNAT, + NFCT_SOPT_UNDO_SPAT, + NFCT_SOPT_UNDO_DPAT, + __NFCT_SOPT_MAX, +}; +#define NFCT_SOPT_MAX (__NFCT_SOPT_MAX - 1) + +/* get option */ +enum { + NFCT_GOPT_IS_SNAT, + NFCT_GOPT_IS_DNAT, + NFCT_GOPT_IS_SPAT, + NFCT_GOPT_IS_DPAT, + __NFCT_GOPT_MAX, +}; +#define NFCT_GOPT_MAX (__NFCT_GOPT_MAX - 1) + +extern int nfct_setobjopt(struct nf_conntrack *ct, unsigned int option); +extern int nfct_getobjopt(const struct nf_conntrack *ct, unsigned int option); + +/* register / unregister callback */ + +extern int nfct_callback_register(struct nfct_handle *h, + enum nf_conntrack_msg_type type, + int (*cb)(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, + void *data), + void *data); + +extern void nfct_callback_unregister(struct nfct_handle *h); + +/* callback verdict */ +enum { + NFCT_CB_FAILURE = -1, /* failure */ + NFCT_CB_STOP = 0, /* stop the query */ + NFCT_CB_CONTINUE = 1, /* keep iterating through data */ + NFCT_CB_STOLEN = 2, /* like continue, but ct is not freed */ +}; + +/* setter */ +extern void nfct_set_attr(struct nf_conntrack *ct, + const enum nf_conntrack_attr type, + void *value); + +extern void nfct_set_attr_u8(struct nf_conntrack *ct, + const enum nf_conntrack_attr type, + u_int8_t value); + +extern void nfct_set_attr_u16(struct nf_conntrack *ct, + const enum nf_conntrack_attr type, + u_int16_t value); + +extern void nfct_set_attr_u32(struct nf_conntrack *ct, + const enum nf_conntrack_attr type, + u_int32_t value); + +/* getter */ +extern const void *nfct_get_attr(const struct nf_conntrack *ct, + const enum nf_conntrack_attr type); + +extern u_int8_t nfct_get_attr_u8(const struct nf_conntrack *ct, + const enum nf_conntrack_attr type); + +extern u_int16_t nfct_get_attr_u16(const struct nf_conntrack *ct, + const enum nf_conntrack_attr type); + +extern u_int32_t nfct_get_attr_u32(const struct nf_conntrack *ct, + const enum nf_conntrack_attr type); + +/* checker */ +extern int nfct_attr_is_set(const struct nf_conntrack *ct, + const enum nf_conntrack_attr type); + +/* unsetter */ +extern int nfct_attr_unset(struct nf_conntrack *ct, + const enum nf_conntrack_attr type); + +/* print */ + +/* output type */ +enum { + NFCT_O_DEFAULT, + NFCT_O_XML, + NFCT_O_MAX +}; + +/* output flags */ +enum { + NFCT_OF_SHOW_LAYER3_BIT = 0, + NFCT_OF_SHOW_LAYER3 = (1 << NFCT_OF_SHOW_LAYER3_BIT), +}; + +extern int nfct_snprintf(char *buf, + unsigned int size, + const struct nf_conntrack *ct, + const unsigned int msg_type, + const unsigned int out_type, + const unsigned int out_flags); + +/* query */ +enum nf_conntrack_query { + NFCT_Q_CREATE, + NFCT_Q_UPDATE, + NFCT_Q_DESTROY, + NFCT_Q_GET, + NFCT_Q_FLUSH, + NFCT_Q_DUMP, + NFCT_Q_DUMP_RESET, +}; + +extern int nfct_query(struct nfct_handle *h, + const enum nf_conntrack_query query, + const void *data); + +extern int nfct_catch(struct nfct_handle *h); + +/* low level API: netlink functions */ + +extern int nfct_build_conntrack(struct nfnl_subsys_handle *ssh, + void *req, + size_t size, + u_int16_t type, + u_int16_t flags, + const struct nf_conntrack *ct); + +extern int nfct_parse_conntrack(enum nf_conntrack_msg_type msg, + const struct nlmsghdr *nlh, + struct nf_conntrack *ct); +extern int nfct_build_query(struct nfnl_subsys_handle *ssh, + const enum nf_conntrack_query query, + const void *data, + void *req, + unsigned int size); #endif /* _LIBNETFILTER_CONNTRACK_H_ */ diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h b/include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h index 1fde6cc..c27d20b 100644 --- a/include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h +++ b/include/libnetfilter_conntrack/libnetfilter_conntrack_tcp.h @@ -8,6 +8,21 @@ #ifndef _LIBNETFILTER_CONNTRACK_TCP_H_ #define _LIBNETFILTER_CONNTRACK_TCP_H_ +enum tcp_state { + TCP_CONNTRACK_NONE, + TCP_CONNTRACK_SYN_SENT, + TCP_CONNTRACK_SYN_RECV, + TCP_CONNTRACK_ESTABLISHED, + TCP_CONNTRACK_FIN_WAIT, + TCP_CONNTRACK_CLOSE_WAIT, + TCP_CONNTRACK_LAST_ACK, + TCP_CONNTRACK_TIME_WAIT, + TCP_CONNTRACK_CLOSE, + TCP_CONNTRACK_LISTEN, + TCP_CONNTRACK_MAX, + TCP_CONNTRACK_IGNORE +}; + enum tcp_flags { TCP_ORIG_SPORT_BIT = 0, TCP_ORIG_SPORT = (1 << TCP_ORIG_SPORT_BIT), diff --git a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h index a1b44bd..b7a0380 100644 --- a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h +++ b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h @@ -27,13 +27,15 @@ enum ctattr_type { CTA_STATUS, CTA_PROTOINFO, CTA_HELP, - CTA_NAT, + CTA_NAT_SRC, +#define CTA_NAT CTA_NAT_SRC /* backwards compatibility */ CTA_TIMEOUT, CTA_MARK, CTA_COUNTERS_ORIG, CTA_COUNTERS_REPLY, CTA_USE, CTA_ID, + CTA_NAT_DST, __CTA_MAX }; #define CTA_MAX (__CTA_MAX - 1) -- cgit v1.2.3