[netfilter-cvslog] r6963 - in tags/libnetfilter_conntrack: .
libnetfilter_conntrack-0.0.81
libnetfilter_conntrack-0.0.81/include/libnetfilter_conntrack
libnetfilter_conntrack-0.0.81/src
libnetfilter_conntrack-0.0.81/src/conntrack
pablo at netfilter.org
pablo at netfilter.org
Sat Jul 28 14:31:57 CEST 2007
Author: pablo at netfilter.org
Date: 2007-07-28 14:31:57 +0200 (Sat, 28 Jul 2007)
New Revision: 6963
Added:
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/configure.in
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/include/libnetfilter_conntrack/libnetfilter_conntrack.h
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/build.c
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/compare.c
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/libnetfilter_conntrack.c
Removed:
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/configure.in
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/include/libnetfilter_conntrack/libnetfilter_conntrack.h
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/build.c
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/compare.c
tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/libnetfilter_conntrack.c
Log:
libnetfilter_conntrack 0.0.81 release tag
Copied: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81 (from rev 6889, trunk/libnetfilter_conntrack)
Deleted: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/configure.in
===================================================================
--- trunk/libnetfilter_conntrack/configure.in 2007-06-25 14:55:18 UTC (rev 6889)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/configure.in 2007-07-28 12:31:57 UTC (rev 6963)
@@ -1,74 +0,0 @@
-dnl Process this file with autoconf to create configure.
-
-AC_INIT
-
-AC_CANONICAL_SYSTEM
-
-AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.80)
-
-AC_PROG_CC
-AM_PROG_LIBTOOL
-AC_PROG_INSTALL
-AC_PROG_LN_S
-
-AC_SUBST(LIBTOOL_DEPS)
-
-case $target in
-*-*-linux*) ;;
-*) AC_MSG_ERROR([Linux only, dude!]);;
-esac
-
-dnl Dependencies
-LIBNFNETLINK_REQUIRED=0.0.25
-
-PKG_CHECK_MODULES(LIBNFNETLINK, libnfnetlink >= $LIBNFNETLINK_REQUIRED,,
- AC_MSG_ERROR(Cannot find libnfnetlink >= $LIBNFNETLINK_REQUIRED))
-
-AC_CHECK_HEADERS(arpa/inet.h)
-dnl Check for inet_ntop
-AC_CHECK_FUNCS(inet_ntop)
-dnl Again, some systems have it, but not IPv6
-if test "$ac_cv_func_inet_ntop" = "yes" ; then
-AC_MSG_CHECKING(if inet_ntop supports IPv6)
-AC_TRY_RUN(
- [
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#include <errno.h>
-int main()
- {
- struct in6_addr addr6;
- char buf[128];
- if (inet_ntop(AF_INET6, &addr6, buf, 128) == 0 && errno == EAFNOSUPPORT)
- exit(1);
- else
- exit(0);
- }
- ], [ AC_MSG_RESULT(yes)
- AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6, 1, [Define to 1 if inet_ntop supports IPv6.])
- ], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
-fi
-
-if test ! -z "$libdir"; then
- MODULE_DIR="\\\"$libdir/libnetfilter_conntrack/\\\""
- CFLAGS="$CFLAGS -DLIBNETFILTER_CONNTRACK_DIR=$MODULE_DIR"
-fi
-
-CFLAGS="$CFLAGS $LIBNFNETLINK_CFLAGS"
-LIBNFCONNTRACK_LIBS="$LIBNFNETLINK_LIBS"
-
-AC_SUBST(LIBNFCONNTRACK_LIBS)
-
-dnl Output the makefile
-AC_OUTPUT(Makefile src/Makefile include/Makefile utils/Makefile include/libnetfilter_conntrack/Makefile l3extensions/Makefile extensions/Makefile src/conntrack/Makefile src/expect/Makefile libnetfilter_conntrack.pc)
-
Copied: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/configure.in (from rev 6902, trunk/libnetfilter_conntrack/configure.in)
===================================================================
--- tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/configure.in (rev 0)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/configure.in 2007-07-28 12:31:57 UTC (rev 6963)
@@ -0,0 +1,74 @@
+dnl Process this file with autoconf to create configure.
+
+AC_INIT
+
+AC_CANONICAL_SYSTEM
+
+AM_INIT_AUTOMAKE(libnetfilter_conntrack, 0.0.81)
+
+AC_PROG_CC
+AM_PROG_LIBTOOL
+AC_PROG_INSTALL
+AC_PROG_LN_S
+
+AC_SUBST(LIBTOOL_DEPS)
+
+case $target in
+*-*-linux*) ;;
+*) AC_MSG_ERROR([Linux only, dude!]);;
+esac
+
+dnl Dependencies
+LIBNFNETLINK_REQUIRED=0.0.25
+
+PKG_CHECK_MODULES(LIBNFNETLINK, libnfnetlink >= $LIBNFNETLINK_REQUIRED,,
+ AC_MSG_ERROR(Cannot find libnfnetlink >= $LIBNFNETLINK_REQUIRED))
+
+AC_CHECK_HEADERS(arpa/inet.h)
+dnl Check for inet_ntop
+AC_CHECK_FUNCS(inet_ntop)
+dnl Again, some systems have it, but not IPv6
+if test "$ac_cv_func_inet_ntop" = "yes" ; then
+AC_MSG_CHECKING(if inet_ntop supports IPv6)
+AC_TRY_RUN(
+ [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <errno.h>
+int main()
+ {
+ struct in6_addr addr6;
+ char buf[128];
+ if (inet_ntop(AF_INET6, &addr6, buf, 128) == 0 && errno == EAFNOSUPPORT)
+ exit(1);
+ else
+ exit(0);
+ }
+ ], [ AC_MSG_RESULT(yes)
+ AC_DEFINE_UNQUOTED(HAVE_INET_NTOP_IPV6, 1, [Define to 1 if inet_ntop supports IPv6.])
+ ], AC_MSG_RESULT(no),AC_MSG_RESULT(no))
+fi
+
+if test ! -z "$libdir"; then
+ MODULE_DIR="\\\"$libdir/libnetfilter_conntrack/\\\""
+ CFLAGS="$CFLAGS -DLIBNETFILTER_CONNTRACK_DIR=$MODULE_DIR"
+fi
+
+CFLAGS="$CFLAGS $LIBNFNETLINK_CFLAGS"
+LIBNFCONNTRACK_LIBS="$LIBNFNETLINK_LIBS"
+
+AC_SUBST(LIBNFCONNTRACK_LIBS)
+
+dnl Output the makefile
+AC_OUTPUT(Makefile src/Makefile include/Makefile utils/Makefile include/libnetfilter_conntrack/Makefile l3extensions/Makefile extensions/Makefile src/conntrack/Makefile src/expect/Makefile libnetfilter_conntrack.pc)
+
Deleted: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/include/libnetfilter_conntrack/libnetfilter_conntrack.h
===================================================================
--- trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h 2007-06-25 14:55:18 UTC (rev 6889)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/include/libnetfilter_conntrack/libnetfilter_conntrack.h 2007-07-28 12:31:57 UTC (rev 6963)
@@ -1,675 +0,0 @@
-/*
- * (C) 2005-2007 by Pablo Neira Ayuso <pablo at netfilter.org>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- */
-
-#ifndef _LIBNETFILTER_CONNTRACK_H_
-#define _LIBNETFILTER_CONNTRACK_H_
-
-#include <netinet/in.h>
-#include <libnfnetlink/linux_nfnetlink.h>
-#include <libnfnetlink/libnfnetlink.h>
-#include <libnetfilter_conntrack/linux_nfnetlink_conntrack.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
- CONNTRACK = NFNL_SUBSYS_CTNETLINK,
- EXPECT = NFNL_SUBSYS_CTNETLINK_EXP
-};
-
-/*
- * Subscribe to all possible conntrack event groups. Use this
- * flag in case that you want to catch up all the possible
- * events. Do not use this flag for dumping or any other
- * similar operation.
- */
-#define NFCT_ALL_CT_GROUPS (NF_NETLINK_CONNTRACK_NEW|NF_NETLINK_CONNTRACK_UPDATE|NF_NETLINK_CONNTRACK_DESTROY)
-
-struct nfct_handle;
-
-/*
- * [Open|close] a conntrack handler
- */
-extern struct nfct_handle *nfct_open(u_int8_t, unsigned);
-extern struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh,
- u_int8_t subsys_id,
- unsigned int subscriptions);
-extern int nfct_close(struct nfct_handle *cth);
-
-extern int nfct_fd(struct nfct_handle *cth);
-
-/*
- * NEW libnetfilter_conntrack API
- */
-
-/* high level API */
-
-#include <sys/types.h>
-
-/* conntrack object */
-struct nf_conntrack;
-
-/* conntrack attributes */
-enum nf_conntrack_attr {
- ATTR_ORIG_IPV4_SRC = 0, /* u32 bits */
- ATTR_IPV4_SRC = ATTR_ORIG_IPV4_SRC, /* alias */
- ATTR_ORIG_IPV4_DST, /* u32 bits */
- ATTR_IPV4_DST = ATTR_ORIG_IPV4_DST, /* alias */
- ATTR_REPL_IPV4_SRC, /* u32 bits */
- ATTR_REPL_IPV4_DST, /* u32 bits */
- ATTR_ORIG_IPV6_SRC = 4, /* u128 bits */
- ATTR_IPV6_SRC = ATTR_ORIG_IPV6_SRC, /* alias */
- ATTR_ORIG_IPV6_DST, /* u128 bits */
- ATTR_IPV6_DST = ATTR_ORIG_IPV6_DST, /* alias */
- ATTR_REPL_IPV6_SRC, /* u128 bits */
- ATTR_REPL_IPV6_DST, /* u128 bits */
- ATTR_ORIG_PORT_SRC = 8, /* u16 bits */
- ATTR_PORT_SRC = ATTR_ORIG_PORT_SRC, /* alias */
- ATTR_ORIG_PORT_DST, /* u16 bits */
- ATTR_PORT_DST = ATTR_ORIG_PORT_DST, /* alias */
- 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, /* u16 bits */
- ATTR_ORIG_L3PROTO, /* u8 bits */
- ATTR_L3PROTO = ATTR_ORIG_L3PROTO, /* alias */
- ATTR_REPL_L3PROTO = 16, /* u8 bits */
- ATTR_ORIG_L4PROTO, /* u8 bits */
- ATTR_L4PROTO = ATTR_ORIG_L4PROTO, /* alias */
- 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);
-
-/* maximum object size */
-extern size_t nfct_maxsize(void);
-
-/* set option */
-enum {
- NFCT_SOPT_UNDO_SNAT,
- NFCT_SOPT_UNDO_DNAT,
- NFCT_SOPT_UNDO_SPAT,
- NFCT_SOPT_UNDO_DPAT,
- NFCT_SOPT_SETUP_ORIGINAL,
- NFCT_SOPT_SETUP_REPLY,
- __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,
- const 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_PLAIN,
- NFCT_O_DEFAULT = NFCT_O_PLAIN,
- 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);
-
-extern int nfct_compare(const struct nf_conntrack *ct1,
- const struct nf_conntrack *ct2);
-
-/* 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,
- NFCT_Q_CREATE_UPDATE,
-};
-
-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);
-
-/*
- * NEW expectation API
- */
-
-/* expectation object */
-struct nf_expect;
-
-/* expect attributes */
-enum nf_expect_attr {
- ATTR_EXP_MASTER = 0, /* pointer to conntrack object */
- ATTR_EXP_EXPECTED, /* pointer to conntrack object */
- ATTR_EXP_MASK, /* pointer to conntrack object */
- ATTR_EXP_TIMEOUT, /* u32 bits */
- ATTR_EXP_MAX
-};
-
-/* constructor / destructor */
-extern struct nf_expect *nfexp_new(void);
-extern void nfexp_destroy(struct nf_expect *exp);
-
-/* clone */
-extern struct nf_expect *nfexp_clone(const struct nf_expect *exp);
-
-/* object size */
-extern size_t nfexp_sizeof(const struct nf_expect *exp);
-
-/* maximum object size */
-extern size_t nfexp_maxsize(void);
-
-/* register / unregister callback */
-
-extern int nfexp_callback_register(struct nfct_handle *h,
- enum nf_conntrack_msg_type type,
- int (*cb)(enum nf_conntrack_msg_type type,
- struct nf_expect *exp,
- void *data),
- void *data);
-
-extern void nfexp_callback_unregister(struct nfct_handle *h);
-
-/* setter */
-extern void nfexp_set_attr(struct nf_expect *exp,
- const enum nf_expect_attr type,
- const void *value);
-
-extern void nfexp_set_attr_u8(struct nf_expect *exp,
- const enum nf_expect_attr type,
- u_int8_t value);
-
-extern void nfexp_set_attr_u16(struct nf_expect *exp,
- const enum nf_expect_attr type,
- u_int16_t value);
-
-extern void nfexp_set_attr_u32(struct nf_expect *exp,
- const enum nf_expect_attr type,
- u_int32_t value);
-
-/* getter */
-extern const void *nfexp_get_attr(const struct nf_expect *exp,
- const enum nf_expect_attr type);
-
-extern u_int8_t nfexp_get_attr_u8(const struct nf_expect *exp,
- const enum nf_expect_attr type);
-
-extern u_int16_t nfexp_get_attr_u16(const struct nf_expect *exp,
- const enum nf_expect_attr type);
-
-extern u_int32_t nfexp_get_attr_u32(const struct nf_expect *exp,
- const enum nf_expect_attr type);
-
-/* checker */
-extern int nfexp_attr_is_set(const struct nf_expect *exp,
- const enum nf_expect_attr type);
-
-/* unsetter */
-extern int nfexp_attr_unset(struct nf_expect *exp,
- const enum nf_expect_attr type);
-
-/* query */
-extern int nfexp_query(struct nfct_handle *h,
- const enum nf_conntrack_query qt,
- const void *data);
-
-/* print */
-extern int nfexp_snprintf(char *buf,
- unsigned int size,
- const struct nf_expect *exp,
- const unsigned int msg_type,
- const unsigned int out_type,
- const unsigned int out_flags);
-
-extern int nfexp_catch(struct nfct_handle *h);
-
-/* Bitset representing status of connection. Taken from ip_conntrack.h
- *
- * Note: For backward compatibility this shouldn't ever change
- * in kernel space.
- */
-enum ip_conntrack_status {
- /* It's an expected connection: bit 0 set. This bit never changed */
- IPS_EXPECTED_BIT = 0,
- IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
-
- /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
- IPS_SEEN_REPLY_BIT = 1,
- IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
-
- /* Conntrack should never be early-expired. */
- IPS_ASSURED_BIT = 2,
- IPS_ASSURED = (1 << IPS_ASSURED_BIT),
-
- /* Connection is confirmed: originating packet has left box */
- IPS_CONFIRMED_BIT = 3,
- IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
-
- /* Connection needs src nat in orig dir. This bit never changed. */
- IPS_SRC_NAT_BIT = 4,
- IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
-
- /* Connection needs dst nat in orig dir. This bit never changed. */
- IPS_DST_NAT_BIT = 5,
- IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
-
- /* Both together. */
- IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
-
- /* Connection needs TCP sequence adjusted. */
- IPS_SEQ_ADJUST_BIT = 6,
- IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
-
- /* NAT initialization bits. */
- IPS_SRC_NAT_DONE_BIT = 7,
- IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
-
- IPS_DST_NAT_DONE_BIT = 8,
- IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
-
- /* Both together */
- IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
-
- /* Connection is dying (removed from lists), can not be unset. */
- IPS_DYING_BIT = 9,
- IPS_DYING = (1 << IPS_DYING_BIT),
-
- /* Connection has fixed timeout. */
- IPS_FIXED_TIMEOUT_BIT = 10,
- IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
-};
-
-/*
- * Old deprecated API, its use for new applications is *strongly discouraged*
- */
-
-/*
- * In case that the user doesn't want to do some kind
- * of action against a conntrack based on its ID
- */
-#define NFCT_ANY_ID 0
-
-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;
- u_int32_t v6[4];
-};
-
-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 NFCT_DIR_ORIGINAL 0
-#define NFCT_DIR_REPLY 1
-#define NFCT_DIR_MAX NFCT_DIR_REPLY+1
-
-struct nfct_conntrack {
- struct nfct_tuple tuple[NFCT_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[NFCT_DIR_MAX];
- struct nfct_nat nat;
-};
-
-struct nfct_expect {
- struct nfct_tuple master;
- struct nfct_tuple tuple;
- struct nfct_tuple mask;
- u_int32_t timeout;
- u_int32_t id;
- u_int16_t expectfn_queue_id;
-};
-
-struct nfct_conntrack_compare {
- struct nfct_conntrack *ct;
- unsigned int flags;
- unsigned int l3flags;
- unsigned int l4flags;
-};
-
-enum {
- NFCT_STATUS_BIT = 0,
- NFCT_STATUS = (1 << NFCT_STATUS_BIT),
-
- NFCT_PROTOINFO_BIT = 1,
- NFCT_PROTOINFO = (1 << NFCT_PROTOINFO_BIT),
-
- NFCT_TIMEOUT_BIT = 2,
- NFCT_TIMEOUT = (1 << NFCT_TIMEOUT_BIT),
-
- NFCT_MARK_BIT = 3,
- NFCT_MARK = (1 << NFCT_MARK_BIT),
-
- NFCT_COUNTERS_ORIG_BIT = 4,
- NFCT_COUNTERS_ORIG = (1 << NFCT_COUNTERS_ORIG_BIT),
-
- NFCT_COUNTERS_RPLY_BIT = 5,
- NFCT_COUNTERS_RPLY = (1 << NFCT_COUNTERS_RPLY_BIT),
-
- NFCT_USE_BIT = 6,
- NFCT_USE = (1 << NFCT_USE_BIT),
-
- NFCT_ID_BIT = 7,
- NFCT_ID = (1 << NFCT_ID_BIT)
-};
-
-enum {
- NFCT_MSG_UNKNOWN,
- NFCT_MSG_NEW,
- NFCT_MSG_UPDATE,
- NFCT_MSG_DESTROY
-};
-
-typedef int (*nfct_callback)(void *arg, unsigned int flags, int, void *data);
-
-/*
- * [Allocate|free] a conntrack
- */
-extern struct nfct_conntrack *
-nfct_conntrack_alloc(struct nfct_tuple *orig, struct nfct_tuple *reply,
- u_int32_t timeout, union nfct_protoinfo *proto,
- u_int32_t status, u_int32_t mark,
- u_int32_t id, struct nfct_nat *range);
-extern void nfct_conntrack_free(struct nfct_conntrack *ct);
-
-/*
- * [Allocate|free] an expectation
- */
-extern struct nfct_expect *
-nfct_expect_alloc(struct nfct_tuple *master, struct nfct_tuple *tuple,
- struct nfct_tuple *mask, u_int32_t timeout,
- u_int32_t id);
-extern void nfct_expect_free(struct nfct_expect *exp);
-
-
-/*
- * [Register|unregister] callbacks
- */
-extern void nfct_register_callback(struct nfct_handle *cth,
- nfct_callback callback, void *data);
-extern void nfct_unregister_callback(struct nfct_handle *cth);
-
-/*
- * callback displayers
- */
-extern int nfct_default_conntrack_display(void *, unsigned int, int, void *);
-extern int nfct_default_conntrack_display_id(void *, unsigned int, int, void *);
-extern int nfct_default_expect_display(void *, unsigned int, int, void *);
-extern int nfct_default_expect_display_id(void *, unsigned int, int, void *);
-extern int nfct_default_conntrack_event_display(void *, unsigned int, int,
- void *);
-
-/*
- * [Create|update|get|destroy] conntracks
- */
-extern int nfct_create_conntrack(struct nfct_handle *cth,
- struct nfct_conntrack *ct);
-extern int nfct_update_conntrack(struct nfct_handle *cth,
- struct nfct_conntrack *ct);
-extern int nfct_delete_conntrack(struct nfct_handle *cth,
- struct nfct_tuple *tuple, int dir,
- u_int32_t id);
-extern int nfct_get_conntrack(struct nfct_handle *cth,
- struct nfct_tuple *tuple, int dir,
- u_int32_t id);
-/*
- * Conntrack table dumping & zeroing
- */
-extern int nfct_dump_conntrack_table(struct nfct_handle *cth, int family);
-extern int nfct_dump_conntrack_table_reset_counters(struct nfct_handle *cth,
- int family);
-
-/*
- * Conntrack event notification
- */
-extern int nfct_event_conntrack(struct nfct_handle *cth);
-
-/*
- * Conntrack printing functions
- */
-extern int nfct_sprintf_conntrack(char *buf, struct nfct_conntrack *ct,
- unsigned int flags);
-extern int nfct_sprintf_conntrack_id(char *buf, struct nfct_conntrack *ct,
- unsigned int flags);
-extern int nfct_sprintf_address(char *buf, struct nfct_tuple *t);
-extern int nfct_sprintf_proto(char *buf, struct nfct_tuple *t);
-extern int nfct_sprintf_protoinfo(char *buf, struct nfct_conntrack *ct);
-extern int nfct_sprintf_timeout(char *buf, struct nfct_conntrack *ct);
-extern int nfct_sprintf_protocol(char *buf, struct nfct_conntrack *ct);
-extern int nfct_sprintf_status_assured(char *buf, struct nfct_conntrack *ct);
-extern int nfct_sprintf_status_seen_reply(char *buf, struct nfct_conntrack *ct);
-extern int nfct_sprintf_counters(char *buf, struct nfct_conntrack *ct, int dir);
-extern int nfct_sprintf_mark(char *buf, struct nfct_conntrack *ct);
-extern int nfct_sprintf_use(char *buf, struct nfct_conntrack *ct);
-extern int nfct_sprintf_id(char *buf, u_int32_t id);
-
-/*
- * Conntrack comparison
- */
-extern int nfct_conntrack_compare(struct nfct_conntrack *ct1,
- struct nfct_conntrack *ct2,
- struct nfct_conntrack_compare *cmp);
-
-/*
- * Expectations
- */
-extern int nfct_dump_expect_list(struct nfct_handle *cth, int family);
-extern int nfct_flush_conntrack_table(struct nfct_handle *cth, int family);
-extern int nfct_get_expectation(struct nfct_handle *cth,
- struct nfct_tuple *tuple,
- u_int32_t id);
-extern int nfct_create_expectation(struct nfct_handle *cth, struct nfct_expect *);
-extern int nfct_delete_expectation(struct nfct_handle *cth,
- struct nfct_tuple *tuple, u_int32_t id);
-extern int nfct_event_expectation(struct nfct_handle *cth);
-extern int nfct_flush_expectation_table(struct nfct_handle *cth, int family);
-
-/*
- * expectation printing functions
- */
-extern int nfct_sprintf_expect(char *buf, struct nfct_expect *exp);
-extern int nfct_sprintf_expect_id(char *buf, struct nfct_expect *exp);
-
-/*
- * low-level functions for libnetfilter_cthelper
- */
-extern void nfct_build_tuple(struct nfnlhdr *req, int size,
- struct nfct_tuple *t, int type);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _LIBNETFILTER_CONNTRACK_H_ */
Copied: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/include/libnetfilter_conntrack/libnetfilter_conntrack.h (from rev 6902, trunk/libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h)
===================================================================
--- tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/include/libnetfilter_conntrack/libnetfilter_conntrack.h (rev 0)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/include/libnetfilter_conntrack/libnetfilter_conntrack.h 2007-07-28 12:31:57 UTC (rev 6963)
@@ -0,0 +1,676 @@
+/*
+ * (C) 2005-2007 by Pablo Neira Ayuso <pablo at netfilter.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
+
+#ifndef _LIBNETFILTER_CONNTRACK_H_
+#define _LIBNETFILTER_CONNTRACK_H_
+
+#include <netinet/in.h>
+#include <libnfnetlink/linux_nfnetlink.h>
+#include <libnfnetlink/libnfnetlink.h>
+#include <libnetfilter_conntrack/linux_nfnetlink_conntrack.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+ CONNTRACK = NFNL_SUBSYS_CTNETLINK,
+ EXPECT = NFNL_SUBSYS_CTNETLINK_EXP
+};
+
+/*
+ * Subscribe to all possible conntrack event groups. Use this
+ * flag in case that you want to catch up all the possible
+ * events. Do not use this flag for dumping or any other
+ * similar operation.
+ */
+#define NFCT_ALL_CT_GROUPS (NF_NETLINK_CONNTRACK_NEW|NF_NETLINK_CONNTRACK_UPDATE|NF_NETLINK_CONNTRACK_DESTROY)
+
+struct nfct_handle;
+
+/*
+ * [Open|close] a conntrack handler
+ */
+extern struct nfct_handle *nfct_open(u_int8_t, unsigned);
+extern struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh,
+ u_int8_t subsys_id,
+ unsigned int subscriptions);
+extern int nfct_close(struct nfct_handle *cth);
+
+extern int nfct_fd(struct nfct_handle *cth);
+extern const struct nfnl_handle *nfct_nfnlh(struct nfct_handle *cth);
+
+/*
+ * NEW libnetfilter_conntrack API
+ */
+
+/* high level API */
+
+#include <sys/types.h>
+
+/* conntrack object */
+struct nf_conntrack;
+
+/* conntrack attributes */
+enum nf_conntrack_attr {
+ ATTR_ORIG_IPV4_SRC = 0, /* u32 bits */
+ ATTR_IPV4_SRC = ATTR_ORIG_IPV4_SRC, /* alias */
+ ATTR_ORIG_IPV4_DST, /* u32 bits */
+ ATTR_IPV4_DST = ATTR_ORIG_IPV4_DST, /* alias */
+ ATTR_REPL_IPV4_SRC, /* u32 bits */
+ ATTR_REPL_IPV4_DST, /* u32 bits */
+ ATTR_ORIG_IPV6_SRC = 4, /* u128 bits */
+ ATTR_IPV6_SRC = ATTR_ORIG_IPV6_SRC, /* alias */
+ ATTR_ORIG_IPV6_DST, /* u128 bits */
+ ATTR_IPV6_DST = ATTR_ORIG_IPV6_DST, /* alias */
+ ATTR_REPL_IPV6_SRC, /* u128 bits */
+ ATTR_REPL_IPV6_DST, /* u128 bits */
+ ATTR_ORIG_PORT_SRC = 8, /* u16 bits */
+ ATTR_PORT_SRC = ATTR_ORIG_PORT_SRC, /* alias */
+ ATTR_ORIG_PORT_DST, /* u16 bits */
+ ATTR_PORT_DST = ATTR_ORIG_PORT_DST, /* alias */
+ 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, /* u16 bits */
+ ATTR_ORIG_L3PROTO, /* u8 bits */
+ ATTR_L3PROTO = ATTR_ORIG_L3PROTO, /* alias */
+ ATTR_REPL_L3PROTO = 16, /* u8 bits */
+ ATTR_ORIG_L4PROTO, /* u8 bits */
+ ATTR_L4PROTO = ATTR_ORIG_L4PROTO, /* alias */
+ 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);
+
+/* maximum object size */
+extern size_t nfct_maxsize(void);
+
+/* set option */
+enum {
+ NFCT_SOPT_UNDO_SNAT,
+ NFCT_SOPT_UNDO_DNAT,
+ NFCT_SOPT_UNDO_SPAT,
+ NFCT_SOPT_UNDO_DPAT,
+ NFCT_SOPT_SETUP_ORIGINAL,
+ NFCT_SOPT_SETUP_REPLY,
+ __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,
+ const 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_PLAIN,
+ NFCT_O_DEFAULT = NFCT_O_PLAIN,
+ 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);
+
+extern int nfct_compare(const struct nf_conntrack *ct1,
+ const struct nf_conntrack *ct2);
+
+/* 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,
+ NFCT_Q_CREATE_UPDATE,
+};
+
+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);
+
+/*
+ * NEW expectation API
+ */
+
+/* expectation object */
+struct nf_expect;
+
+/* expect attributes */
+enum nf_expect_attr {
+ ATTR_EXP_MASTER = 0, /* pointer to conntrack object */
+ ATTR_EXP_EXPECTED, /* pointer to conntrack object */
+ ATTR_EXP_MASK, /* pointer to conntrack object */
+ ATTR_EXP_TIMEOUT, /* u32 bits */
+ ATTR_EXP_MAX
+};
+
+/* constructor / destructor */
+extern struct nf_expect *nfexp_new(void);
+extern void nfexp_destroy(struct nf_expect *exp);
+
+/* clone */
+extern struct nf_expect *nfexp_clone(const struct nf_expect *exp);
+
+/* object size */
+extern size_t nfexp_sizeof(const struct nf_expect *exp);
+
+/* maximum object size */
+extern size_t nfexp_maxsize(void);
+
+/* register / unregister callback */
+
+extern int nfexp_callback_register(struct nfct_handle *h,
+ enum nf_conntrack_msg_type type,
+ int (*cb)(enum nf_conntrack_msg_type type,
+ struct nf_expect *exp,
+ void *data),
+ void *data);
+
+extern void nfexp_callback_unregister(struct nfct_handle *h);
+
+/* setter */
+extern void nfexp_set_attr(struct nf_expect *exp,
+ const enum nf_expect_attr type,
+ const void *value);
+
+extern void nfexp_set_attr_u8(struct nf_expect *exp,
+ const enum nf_expect_attr type,
+ u_int8_t value);
+
+extern void nfexp_set_attr_u16(struct nf_expect *exp,
+ const enum nf_expect_attr type,
+ u_int16_t value);
+
+extern void nfexp_set_attr_u32(struct nf_expect *exp,
+ const enum nf_expect_attr type,
+ u_int32_t value);
+
+/* getter */
+extern const void *nfexp_get_attr(const struct nf_expect *exp,
+ const enum nf_expect_attr type);
+
+extern u_int8_t nfexp_get_attr_u8(const struct nf_expect *exp,
+ const enum nf_expect_attr type);
+
+extern u_int16_t nfexp_get_attr_u16(const struct nf_expect *exp,
+ const enum nf_expect_attr type);
+
+extern u_int32_t nfexp_get_attr_u32(const struct nf_expect *exp,
+ const enum nf_expect_attr type);
+
+/* checker */
+extern int nfexp_attr_is_set(const struct nf_expect *exp,
+ const enum nf_expect_attr type);
+
+/* unsetter */
+extern int nfexp_attr_unset(struct nf_expect *exp,
+ const enum nf_expect_attr type);
+
+/* query */
+extern int nfexp_query(struct nfct_handle *h,
+ const enum nf_conntrack_query qt,
+ const void *data);
+
+/* print */
+extern int nfexp_snprintf(char *buf,
+ unsigned int size,
+ const struct nf_expect *exp,
+ const unsigned int msg_type,
+ const unsigned int out_type,
+ const unsigned int out_flags);
+
+extern int nfexp_catch(struct nfct_handle *h);
+
+/* Bitset representing status of connection. Taken from ip_conntrack.h
+ *
+ * Note: For backward compatibility this shouldn't ever change
+ * in kernel space.
+ */
+enum ip_conntrack_status {
+ /* It's an expected connection: bit 0 set. This bit never changed */
+ IPS_EXPECTED_BIT = 0,
+ IPS_EXPECTED = (1 << IPS_EXPECTED_BIT),
+
+ /* We've seen packets both ways: bit 1 set. Can be set, not unset. */
+ IPS_SEEN_REPLY_BIT = 1,
+ IPS_SEEN_REPLY = (1 << IPS_SEEN_REPLY_BIT),
+
+ /* Conntrack should never be early-expired. */
+ IPS_ASSURED_BIT = 2,
+ IPS_ASSURED = (1 << IPS_ASSURED_BIT),
+
+ /* Connection is confirmed: originating packet has left box */
+ IPS_CONFIRMED_BIT = 3,
+ IPS_CONFIRMED = (1 << IPS_CONFIRMED_BIT),
+
+ /* Connection needs src nat in orig dir. This bit never changed. */
+ IPS_SRC_NAT_BIT = 4,
+ IPS_SRC_NAT = (1 << IPS_SRC_NAT_BIT),
+
+ /* Connection needs dst nat in orig dir. This bit never changed. */
+ IPS_DST_NAT_BIT = 5,
+ IPS_DST_NAT = (1 << IPS_DST_NAT_BIT),
+
+ /* Both together. */
+ IPS_NAT_MASK = (IPS_DST_NAT | IPS_SRC_NAT),
+
+ /* Connection needs TCP sequence adjusted. */
+ IPS_SEQ_ADJUST_BIT = 6,
+ IPS_SEQ_ADJUST = (1 << IPS_SEQ_ADJUST_BIT),
+
+ /* NAT initialization bits. */
+ IPS_SRC_NAT_DONE_BIT = 7,
+ IPS_SRC_NAT_DONE = (1 << IPS_SRC_NAT_DONE_BIT),
+
+ IPS_DST_NAT_DONE_BIT = 8,
+ IPS_DST_NAT_DONE = (1 << IPS_DST_NAT_DONE_BIT),
+
+ /* Both together */
+ IPS_NAT_DONE_MASK = (IPS_DST_NAT_DONE | IPS_SRC_NAT_DONE),
+
+ /* Connection is dying (removed from lists), can not be unset. */
+ IPS_DYING_BIT = 9,
+ IPS_DYING = (1 << IPS_DYING_BIT),
+
+ /* Connection has fixed timeout. */
+ IPS_FIXED_TIMEOUT_BIT = 10,
+ IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
+};
+
+/*
+ * Old deprecated API, its use for new applications is *strongly discouraged*
+ */
+
+/*
+ * In case that the user doesn't want to do some kind
+ * of action against a conntrack based on its ID
+ */
+#define NFCT_ANY_ID 0
+
+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;
+ u_int32_t v6[4];
+};
+
+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 NFCT_DIR_ORIGINAL 0
+#define NFCT_DIR_REPLY 1
+#define NFCT_DIR_MAX NFCT_DIR_REPLY+1
+
+struct nfct_conntrack {
+ struct nfct_tuple tuple[NFCT_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[NFCT_DIR_MAX];
+ struct nfct_nat nat;
+};
+
+struct nfct_expect {
+ struct nfct_tuple master;
+ struct nfct_tuple tuple;
+ struct nfct_tuple mask;
+ u_int32_t timeout;
+ u_int32_t id;
+ u_int16_t expectfn_queue_id;
+};
+
+struct nfct_conntrack_compare {
+ struct nfct_conntrack *ct;
+ unsigned int flags;
+ unsigned int l3flags;
+ unsigned int l4flags;
+};
+
+enum {
+ NFCT_STATUS_BIT = 0,
+ NFCT_STATUS = (1 << NFCT_STATUS_BIT),
+
+ NFCT_PROTOINFO_BIT = 1,
+ NFCT_PROTOINFO = (1 << NFCT_PROTOINFO_BIT),
+
+ NFCT_TIMEOUT_BIT = 2,
+ NFCT_TIMEOUT = (1 << NFCT_TIMEOUT_BIT),
+
+ NFCT_MARK_BIT = 3,
+ NFCT_MARK = (1 << NFCT_MARK_BIT),
+
+ NFCT_COUNTERS_ORIG_BIT = 4,
+ NFCT_COUNTERS_ORIG = (1 << NFCT_COUNTERS_ORIG_BIT),
+
+ NFCT_COUNTERS_RPLY_BIT = 5,
+ NFCT_COUNTERS_RPLY = (1 << NFCT_COUNTERS_RPLY_BIT),
+
+ NFCT_USE_BIT = 6,
+ NFCT_USE = (1 << NFCT_USE_BIT),
+
+ NFCT_ID_BIT = 7,
+ NFCT_ID = (1 << NFCT_ID_BIT)
+};
+
+enum {
+ NFCT_MSG_UNKNOWN,
+ NFCT_MSG_NEW,
+ NFCT_MSG_UPDATE,
+ NFCT_MSG_DESTROY
+};
+
+typedef int (*nfct_callback)(void *arg, unsigned int flags, int, void *data);
+
+/*
+ * [Allocate|free] a conntrack
+ */
+extern struct nfct_conntrack *
+nfct_conntrack_alloc(struct nfct_tuple *orig, struct nfct_tuple *reply,
+ u_int32_t timeout, union nfct_protoinfo *proto,
+ u_int32_t status, u_int32_t mark,
+ u_int32_t id, struct nfct_nat *range);
+extern void nfct_conntrack_free(struct nfct_conntrack *ct);
+
+/*
+ * [Allocate|free] an expectation
+ */
+extern struct nfct_expect *
+nfct_expect_alloc(struct nfct_tuple *master, struct nfct_tuple *tuple,
+ struct nfct_tuple *mask, u_int32_t timeout,
+ u_int32_t id);
+extern void nfct_expect_free(struct nfct_expect *exp);
+
+
+/*
+ * [Register|unregister] callbacks
+ */
+extern void nfct_register_callback(struct nfct_handle *cth,
+ nfct_callback callback, void *data);
+extern void nfct_unregister_callback(struct nfct_handle *cth);
+
+/*
+ * callback displayers
+ */
+extern int nfct_default_conntrack_display(void *, unsigned int, int, void *);
+extern int nfct_default_conntrack_display_id(void *, unsigned int, int, void *);
+extern int nfct_default_expect_display(void *, unsigned int, int, void *);
+extern int nfct_default_expect_display_id(void *, unsigned int, int, void *);
+extern int nfct_default_conntrack_event_display(void *, unsigned int, int,
+ void *);
+
+/*
+ * [Create|update|get|destroy] conntracks
+ */
+extern int nfct_create_conntrack(struct nfct_handle *cth,
+ struct nfct_conntrack *ct);
+extern int nfct_update_conntrack(struct nfct_handle *cth,
+ struct nfct_conntrack *ct);
+extern int nfct_delete_conntrack(struct nfct_handle *cth,
+ struct nfct_tuple *tuple, int dir,
+ u_int32_t id);
+extern int nfct_get_conntrack(struct nfct_handle *cth,
+ struct nfct_tuple *tuple, int dir,
+ u_int32_t id);
+/*
+ * Conntrack table dumping & zeroing
+ */
+extern int nfct_dump_conntrack_table(struct nfct_handle *cth, int family);
+extern int nfct_dump_conntrack_table_reset_counters(struct nfct_handle *cth,
+ int family);
+
+/*
+ * Conntrack event notification
+ */
+extern int nfct_event_conntrack(struct nfct_handle *cth);
+
+/*
+ * Conntrack printing functions
+ */
+extern int nfct_sprintf_conntrack(char *buf, struct nfct_conntrack *ct,
+ unsigned int flags);
+extern int nfct_sprintf_conntrack_id(char *buf, struct nfct_conntrack *ct,
+ unsigned int flags);
+extern int nfct_sprintf_address(char *buf, struct nfct_tuple *t);
+extern int nfct_sprintf_proto(char *buf, struct nfct_tuple *t);
+extern int nfct_sprintf_protoinfo(char *buf, struct nfct_conntrack *ct);
+extern int nfct_sprintf_timeout(char *buf, struct nfct_conntrack *ct);
+extern int nfct_sprintf_protocol(char *buf, struct nfct_conntrack *ct);
+extern int nfct_sprintf_status_assured(char *buf, struct nfct_conntrack *ct);
+extern int nfct_sprintf_status_seen_reply(char *buf, struct nfct_conntrack *ct);
+extern int nfct_sprintf_counters(char *buf, struct nfct_conntrack *ct, int dir);
+extern int nfct_sprintf_mark(char *buf, struct nfct_conntrack *ct);
+extern int nfct_sprintf_use(char *buf, struct nfct_conntrack *ct);
+extern int nfct_sprintf_id(char *buf, u_int32_t id);
+
+/*
+ * Conntrack comparison
+ */
+extern int nfct_conntrack_compare(struct nfct_conntrack *ct1,
+ struct nfct_conntrack *ct2,
+ struct nfct_conntrack_compare *cmp);
+
+/*
+ * Expectations
+ */
+extern int nfct_dump_expect_list(struct nfct_handle *cth, int family);
+extern int nfct_flush_conntrack_table(struct nfct_handle *cth, int family);
+extern int nfct_get_expectation(struct nfct_handle *cth,
+ struct nfct_tuple *tuple,
+ u_int32_t id);
+extern int nfct_create_expectation(struct nfct_handle *cth, struct nfct_expect *);
+extern int nfct_delete_expectation(struct nfct_handle *cth,
+ struct nfct_tuple *tuple, u_int32_t id);
+extern int nfct_event_expectation(struct nfct_handle *cth);
+extern int nfct_flush_expectation_table(struct nfct_handle *cth, int family);
+
+/*
+ * expectation printing functions
+ */
+extern int nfct_sprintf_expect(char *buf, struct nfct_expect *exp);
+extern int nfct_sprintf_expect_id(char *buf, struct nfct_expect *exp);
+
+/*
+ * low-level functions for libnetfilter_cthelper
+ */
+extern void nfct_build_tuple(struct nfnlhdr *req, int size,
+ struct nfct_tuple *t, int type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBNETFILTER_CONNTRACK_H_ */
Deleted: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/build.c
===================================================================
--- trunk/libnetfilter_conntrack/src/conntrack/build.c 2007-06-25 14:55:18 UTC (rev 6889)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/build.c 2007-07-28 12:31:57 UTC (rev 6963)
@@ -1,289 +0,0 @@
-/*
- * (C) 2006 by Pablo Neira Ayuso <pablo at netfilter.org>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- */
-
-#include "internal.h"
-
-void __build_tuple_ip(struct nfnlhdr *req,
- size_t size,
- const struct __nfct_tuple *t)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_IP);
-
- switch(t->l3protonum) {
- case AF_INET:
- nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_SRC, &t->src.v4,
- sizeof(u_int32_t));
- nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_DST, &t->dst.v4,
- sizeof(u_int32_t));
- break;
- case AF_INET6:
- nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_SRC, &t->src.v6,
- sizeof(struct in6_addr));
- nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_DST, &t->dst.v6,
- sizeof(struct in6_addr));
- break;
- default:
- break;
- }
-
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_tuple_proto(struct nfnlhdr *req,
- size_t size,
- const struct __nfct_tuple *t)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_PROTO);
-
- nfnl_addattr_l(&req->nlh, size, CTA_PROTO_NUM, &t->protonum,
- sizeof(u_int8_t));
-
- switch(t->protonum) {
- case IPPROTO_UDP:
- case IPPROTO_TCP:
- case IPPROTO_SCTP:
- nfnl_addattr_l(&req->nlh, size, CTA_PROTO_SRC_PORT,
- &t->l4src.tcp.port, sizeof(u_int16_t));
- nfnl_addattr_l(&req->nlh, size, CTA_PROTO_DST_PORT,
- &t->l4dst.tcp.port, sizeof(u_int16_t));
- break;
- case IPPROTO_ICMP:
- nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_CODE,
- &t->l4dst.icmp.code, sizeof(u_int8_t));
- nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_TYPE,
- &t->l4dst.icmp.type, sizeof(u_int8_t));
- nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_ID,
- &t->l4src.icmp.id, sizeof(u_int16_t));
- break;
- default:
- break;
- }
-
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_tuple(struct nfnlhdr *req,
- size_t size,
- const struct __nfct_tuple *t,
- const int type)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, type);
-
- __build_tuple_ip(req, size, t);
- __build_tuple_proto(req, size, t);
-
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_protoinfo(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- struct nfattr *nest, *nest_proto;
-
- switch(ct->tuple[__DIR_ORIG].protonum) {
- case IPPROTO_TCP:
- nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
- nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_TCP);
- nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_STATE,
- &ct->protoinfo.tcp.state, sizeof(u_int8_t));
- nfnl_nest_end(&req->nlh, nest_proto);
- nfnl_nest_end(&req->nlh, nest);
- break;
- default:
- break;
- }
-}
-
-void __build_protonat(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct,
- const struct __nfct_nat *nat)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_NAT_PROTO);
-
- switch (ct->tuple[NFCT_DIR_ORIGINAL].protonum) {
- case IPPROTO_TCP:
- case IPPROTO_UDP:
- nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_PORT_MIN,
- &nat->l4min.tcp.port, sizeof(u_int16_t));
- nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_PORT_MAX,
- &nat->l4max.tcp.port, sizeof(u_int16_t));
- break;
- }
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_nat(struct nfnlhdr *req,
- size_t size,
- const struct __nfct_nat *nat)
-{
- nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP,
- &nat->min_ip, sizeof(u_int32_t));
-}
-
-void __build_snat(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
- __build_nat(req, size, &ct->snat);
- __build_protonat(req, size, ct, &ct->snat);
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_snat_ipv4(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
- __build_nat(req, size, &ct->snat);
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_snat_port(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
- __build_protonat(req, size, ct, &ct->snat);
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_dnat(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
- __build_nat(req, size, &ct->dnat);
- __build_protonat(req, size, ct, &ct->dnat);
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_dnat_ipv4(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
- __build_nat(req, size, &ct->dnat);
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_dnat_port(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
- __build_protonat(req, size, ct, &ct->dnat);
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void __build_status(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- nfnl_addattr32(&req->nlh, size, CTA_STATUS,
- htonl(ct->status | IPS_CONFIRMED));
-}
-
-void __build_timeout(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- nfnl_addattr32(&req->nlh, size, CTA_TIMEOUT, htonl(ct->timeout));
-}
-
-void __build_mark(struct nfnlhdr *req,
- size_t size,
- const struct nf_conntrack *ct)
-{
- nfnl_addattr32(&req->nlh, size, CTA_MARK, htonl(ct->mark));
-}
-
-void __build_id(struct nfnlhdr *req,
- size_t size,
- const const struct nf_conntrack *ct)
-{
- nfnl_addattr32(&req->nlh, size, CTA_ID, htonl(ct->id));
-}
-
-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)
-{
- u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
-
- if (!test_bit(ATTR_ORIG_L3PROTO, ct->set)) {
- errno = EINVAL;
- return -1;
- }
-
- memset(req, 0, size);
-
- nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags);
-
- __build_tuple(req, size, &ct->tuple[__DIR_ORIG], CTA_TUPLE_ORIG);
- __build_tuple(req, size, &ct->tuple[__DIR_REPL], CTA_TUPLE_REPLY);
-
- if (test_bit(ATTR_STATUS, ct->set))
- __build_status(req, size, ct);
- else {
- /* build IPS_CONFIRMED if we're creating a new conntrack */
- if (type == IPCTNL_MSG_CT_NEW && flags & NLM_F_CREATE)
- __build_status(req, size, ct);
- }
-
- if (test_bit(ATTR_TIMEOUT, ct->set))
- __build_timeout(req, size, ct);
-
- if (test_bit(ATTR_MARK, ct->set))
- __build_mark(req, size, ct);
-
- if (test_bit(ATTR_TCP_STATE, ct->set))
- __build_protoinfo(req, size, ct);
-
- if (test_bit(ATTR_SNAT_IPV4, ct->set) &&
- test_bit(ATTR_SNAT_PORT, ct->set))
- __build_snat(req, size, ct);
- else if (test_bit(ATTR_SNAT_IPV4, ct->set))
- __build_snat_ipv4(req, size, ct);
- else if (test_bit(ATTR_SNAT_PORT, ct->set))
- __build_snat_port(req, size, ct);
-
- if (test_bit(ATTR_DNAT_IPV4, ct->set) &&
- test_bit(ATTR_DNAT_PORT, ct->set))
- __build_dnat(req, size, ct);
- else if (test_bit(ATTR_DNAT_IPV4, ct->set))
- __build_dnat_ipv4(req, size, ct);
- else if (test_bit(ATTR_DNAT_PORT, ct->set))
- __build_dnat_port(req, size, ct);
-
- return 0;
-}
Copied: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/build.c (from rev 6902, trunk/libnetfilter_conntrack/src/conntrack/build.c)
===================================================================
--- tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/build.c (rev 0)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/build.c 2007-07-28 12:31:57 UTC (rev 6963)
@@ -0,0 +1,282 @@
+/*
+ * (C) 2006-2007 by Pablo Neira Ayuso <pablo at netfilter.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
+
+#include "internal.h"
+
+void __build_tuple_ip(struct nfnlhdr *req,
+ size_t size,
+ const struct __nfct_tuple *t)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_IP);
+
+ switch(t->l3protonum) {
+ case AF_INET:
+ nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_SRC, &t->src.v4,
+ sizeof(u_int32_t));
+ nfnl_addattr_l(&req->nlh, size, CTA_IP_V4_DST, &t->dst.v4,
+ sizeof(u_int32_t));
+ break;
+ case AF_INET6:
+ nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_SRC, &t->src.v6,
+ sizeof(struct in6_addr));
+ nfnl_addattr_l(&req->nlh, size, CTA_IP_V6_DST, &t->dst.v6,
+ sizeof(struct in6_addr));
+ break;
+ default:
+ break;
+ }
+
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_tuple_proto(struct nfnlhdr *req,
+ size_t size,
+ const struct __nfct_tuple *t)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_PROTO);
+
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTO_NUM, &t->protonum,
+ sizeof(u_int8_t));
+
+ switch(t->protonum) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTO_SRC_PORT,
+ &t->l4src.tcp.port, sizeof(u_int16_t));
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTO_DST_PORT,
+ &t->l4dst.tcp.port, sizeof(u_int16_t));
+ break;
+ case IPPROTO_ICMP:
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_CODE,
+ &t->l4dst.icmp.code, sizeof(u_int8_t));
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_TYPE,
+ &t->l4dst.icmp.type, sizeof(u_int8_t));
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_ID,
+ &t->l4src.icmp.id, sizeof(u_int16_t));
+ break;
+ default:
+ break;
+ }
+
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_tuple(struct nfnlhdr *req,
+ size_t size,
+ const struct __nfct_tuple *t,
+ const int type)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, type);
+
+ __build_tuple_ip(req, size, t);
+ __build_tuple_proto(req, size, t);
+
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_protoinfo(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ struct nfattr *nest, *nest_proto;
+
+ switch(ct->tuple[__DIR_ORIG].protonum) {
+ case IPPROTO_TCP:
+ nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
+ nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_TCP);
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTOINFO_TCP_STATE,
+ &ct->protoinfo.tcp.state, sizeof(u_int8_t));
+ nfnl_nest_end(&req->nlh, nest_proto);
+ nfnl_nest_end(&req->nlh, nest);
+ break;
+ default:
+ break;
+ }
+}
+
+void __build_protonat(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct,
+ const struct __nfct_nat *nat)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_NAT_PROTO);
+
+ switch (ct->tuple[NFCT_DIR_ORIGINAL].protonum) {
+ case IPPROTO_TCP:
+ case IPPROTO_UDP:
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_PORT_MIN,
+ &nat->l4min.tcp.port, sizeof(u_int16_t));
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_PORT_MAX,
+ &nat->l4max.tcp.port, sizeof(u_int16_t));
+ break;
+ }
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_nat(struct nfnlhdr *req,
+ size_t size,
+ const struct __nfct_nat *nat)
+{
+ nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP,
+ &nat->min_ip, sizeof(u_int32_t));
+}
+
+void __build_snat(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
+ __build_nat(req, size, &ct->snat);
+ __build_protonat(req, size, ct, &ct->snat);
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_snat_ipv4(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
+ __build_nat(req, size, &ct->snat);
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_snat_port(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_NAT_SRC);
+ __build_protonat(req, size, ct, &ct->snat);
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_dnat(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
+ __build_nat(req, size, &ct->dnat);
+ __build_protonat(req, size, ct, &ct->dnat);
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_dnat_ipv4(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
+ __build_nat(req, size, &ct->dnat);
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_dnat_port(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_NAT_DST);
+ __build_protonat(req, size, ct, &ct->dnat);
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void __build_status(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ nfnl_addattr32(&req->nlh, size, CTA_STATUS,
+ htonl(ct->status | IPS_CONFIRMED));
+}
+
+void __build_timeout(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ nfnl_addattr32(&req->nlh, size, CTA_TIMEOUT, htonl(ct->timeout));
+}
+
+void __build_mark(struct nfnlhdr *req,
+ size_t size,
+ const struct nf_conntrack *ct)
+{
+ nfnl_addattr32(&req->nlh, size, CTA_MARK, htonl(ct->mark));
+}
+
+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)
+{
+ u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
+
+ if (!test_bit(ATTR_ORIG_L3PROTO, ct->set)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ memset(req, 0, size);
+
+ nfnl_fill_hdr(ssh, &req->nlh, 0, l3num, 0, type, flags);
+
+ __build_tuple(req, size, &ct->tuple[__DIR_ORIG], CTA_TUPLE_ORIG);
+ __build_tuple(req, size, &ct->tuple[__DIR_REPL], CTA_TUPLE_REPLY);
+
+ if (test_bit(ATTR_STATUS, ct->set))
+ __build_status(req, size, ct);
+ else {
+ /* build IPS_CONFIRMED if we're creating a new conntrack */
+ if (type == IPCTNL_MSG_CT_NEW && flags & NLM_F_CREATE)
+ __build_status(req, size, ct);
+ }
+
+ if (test_bit(ATTR_TIMEOUT, ct->set))
+ __build_timeout(req, size, ct);
+
+ if (test_bit(ATTR_MARK, ct->set))
+ __build_mark(req, size, ct);
+
+ if (test_bit(ATTR_TCP_STATE, ct->set))
+ __build_protoinfo(req, size, ct);
+
+ if (test_bit(ATTR_SNAT_IPV4, ct->set) &&
+ test_bit(ATTR_SNAT_PORT, ct->set))
+ __build_snat(req, size, ct);
+ else if (test_bit(ATTR_SNAT_IPV4, ct->set))
+ __build_snat_ipv4(req, size, ct);
+ else if (test_bit(ATTR_SNAT_PORT, ct->set))
+ __build_snat_port(req, size, ct);
+
+ if (test_bit(ATTR_DNAT_IPV4, ct->set) &&
+ test_bit(ATTR_DNAT_PORT, ct->set))
+ __build_dnat(req, size, ct);
+ else if (test_bit(ATTR_DNAT_IPV4, ct->set))
+ __build_dnat_ipv4(req, size, ct);
+ else if (test_bit(ATTR_DNAT_PORT, ct->set))
+ __build_dnat_port(req, size, ct);
+
+ return 0;
+}
Deleted: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/compare.c
===================================================================
--- trunk/libnetfilter_conntrack/src/conntrack/compare.c 2007-06-25 14:55:18 UTC (rev 6889)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/compare.c 2007-07-28 12:31:57 UTC (rev 6963)
@@ -1,102 +0,0 @@
-/*
- * (C) 2007 by Pablo Neira Ayuso <pablo at netfilter.org>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- */
-
-#include "internal.h"
-
-int __compare(const struct nf_conntrack *ct1,
- const struct nf_conntrack *ct2)
-{
- if (test_bit(ATTR_MARK, ct1->set) &&
- test_bit(ATTR_MARK, ct2->set) &&
- ct1->mark != ct2->mark)
- return 0;
-
- if (test_bit(ATTR_TIMEOUT, ct1->set) &&
- test_bit(ATTR_TIMEOUT, ct2->set) &&
- ct1->timeout != ct2->timeout)
- return 0;
-
- if (test_bit(ATTR_STATUS, ct1->set) &&
- test_bit(ATTR_STATUS, ct2->set) &&
- ct1->status == ct2->status)
- return 0;
-
- if (test_bit(ATTR_TCP_STATE, ct1->set) &&
- test_bit(ATTR_TCP_STATE, ct2->set) &&
- ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state)
- return 0;
-
- if (test_bit(ATTR_ORIG_L3PROTO, ct1->set) &&
- test_bit(ATTR_ORIG_L3PROTO, ct2->set) &&
- ct1->tuple[__DIR_ORIG].l3protonum != AF_UNSPEC &&
- ct2->tuple[__DIR_ORIG].l3protonum != AF_UNSPEC &&
- ct1->tuple[__DIR_ORIG].l3protonum !=
- ct2->tuple[__DIR_ORIG].l3protonum)
- return 0;
-
- if (test_bit(ATTR_REPL_L3PROTO, ct1->set) &&
- test_bit(ATTR_REPL_L3PROTO, ct2->set) &&
- ct1->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
- ct2->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
- ct1->tuple[__DIR_REPL].l3protonum !=
- ct2->tuple[__DIR_REPL].l3protonum)
- return 0;
-
- if (test_bit(ATTR_ORIG_IPV4_SRC, ct1->set) &&
- test_bit(ATTR_ORIG_IPV4_SRC, ct2->set) &&
- ct1->tuple[__DIR_ORIG].src.v4 !=
- ct2->tuple[__DIR_ORIG].src.v4)
- return 0;
-
- if (test_bit(ATTR_ORIG_IPV4_DST, ct1->set) &&
- test_bit(ATTR_ORIG_IPV4_DST, ct2->set) &&
- ct1->tuple[__DIR_ORIG].dst.v4 !=
- ct2->tuple[__DIR_ORIG].dst.v4)
- return 0;
-
- if (test_bit(ATTR_REPL_IPV4_SRC, ct1->set) &&
- test_bit(ATTR_REPL_IPV4_SRC, ct2->set) &&
- ct1->tuple[__DIR_REPL].src.v4 !=
- ct2->tuple[__DIR_REPL].src.v4)
- return 0;
-
- if (test_bit(ATTR_REPL_IPV4_DST, ct1->set) &&
- test_bit(ATTR_REPL_IPV4_DST, ct2->set) &&
- ct1->tuple[__DIR_REPL].dst.v4 !=
- ct2->tuple[__DIR_REPL].dst.v4)
- return 0;
-
- if (test_bit(ATTR_ORIG_IPV6_SRC, ct1->set) &&
- test_bit(ATTR_ORIG_IPV6_SRC, ct2->set) &&
- memcmp(&ct1->tuple[__DIR_ORIG].src.v6,
- &ct2->tuple[__DIR_ORIG].src.v6,
- sizeof(u_int32_t)*4) == 0)
- return 0;
-
- if (test_bit(ATTR_ORIG_IPV6_DST, ct1->set) &&
- test_bit(ATTR_ORIG_IPV6_DST, ct2->set) &&
- memcmp(&ct1->tuple[__DIR_ORIG].dst.v6,
- &ct2->tuple[__DIR_ORIG].dst.v6,
- sizeof(u_int32_t)*4) == 0)
- return 0;
-
- if (test_bit(ATTR_REPL_IPV6_SRC, ct1->set) &&
- test_bit(ATTR_REPL_IPV6_SRC, ct2->set) &&
- memcmp(&ct1->tuple[__DIR_REPL].src.v6,
- &ct2->tuple[__DIR_REPL].src.v6,
- sizeof(u_int32_t)*4) == 0)
- return 0;
-
- if (test_bit(ATTR_REPL_IPV6_DST, ct1->set) &&
- test_bit(ATTR_REPL_IPV6_DST, ct2->set) &&
- memcmp(&ct1->tuple[__DIR_REPL].dst.v6,
- &ct2->tuple[__DIR_REPL].dst.v6,
- sizeof(u_int32_t)*4) == 0)
- return 0;
-
- return 1;
-}
Copied: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/compare.c (from rev 6911, trunk/libnetfilter_conntrack/src/conntrack/compare.c)
===================================================================
--- tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/compare.c (rev 0)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/conntrack/compare.c 2007-07-28 12:31:57 UTC (rev 6963)
@@ -0,0 +1,114 @@
+/*
+ * (C) 2007 by Pablo Neira Ayuso <pablo at netfilter.org>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ */
+
+#include "internal.h"
+
+int __compare(const struct nf_conntrack *ct1,
+ const struct nf_conntrack *ct2)
+{
+ if (test_bit(ATTR_MARK, ct1->set) &&
+ test_bit(ATTR_MARK, ct2->set) &&
+ ct1->mark != ct2->mark)
+ return 0;
+
+ if (test_bit(ATTR_TIMEOUT, ct1->set) &&
+ test_bit(ATTR_TIMEOUT, ct2->set) &&
+ ct1->timeout != ct2->timeout)
+ return 0;
+
+ if (test_bit(ATTR_STATUS, ct1->set) &&
+ test_bit(ATTR_STATUS, ct2->set) &&
+ ct1->status == ct2->status)
+ return 0;
+
+ if (test_bit(ATTR_TCP_STATE, ct1->set) &&
+ test_bit(ATTR_TCP_STATE, ct2->set) &&
+ ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state)
+ return 0;
+
+ if (test_bit(ATTR_ORIG_L3PROTO, ct1->set) &&
+ test_bit(ATTR_ORIG_L3PROTO, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].l3protonum != AF_UNSPEC &&
+ ct2->tuple[__DIR_ORIG].l3protonum != AF_UNSPEC &&
+ ct1->tuple[__DIR_ORIG].l3protonum !=
+ ct2->tuple[__DIR_ORIG].l3protonum)
+ return 0;
+
+ if (test_bit(ATTR_REPL_L3PROTO, ct1->set) &&
+ test_bit(ATTR_REPL_L3PROTO, ct2->set) &&
+ ct1->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
+ ct2->tuple[__DIR_REPL].l3protonum != AF_UNSPEC &&
+ ct1->tuple[__DIR_REPL].l3protonum !=
+ ct2->tuple[__DIR_REPL].l3protonum)
+ return 0;
+
+ if (test_bit(ATTR_ORIG_L4PROTO, ct1->set) &&
+ test_bit(ATTR_ORIG_L4PROTO, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].protonum !=
+ ct2->tuple[__DIR_ORIG].protonum)
+ return 0;
+
+ if (test_bit(ATTR_REPL_L4PROTO, ct1->set) &&
+ test_bit(ATTR_REPL_L4PROTO, ct2->set) &&
+ ct1->tuple[__DIR_REPL].protonum !=
+ ct2->tuple[__DIR_REPL].protonum)
+ return 0;
+
+ if (test_bit(ATTR_ORIG_IPV4_SRC, ct1->set) &&
+ test_bit(ATTR_ORIG_IPV4_SRC, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].src.v4 !=
+ ct2->tuple[__DIR_ORIG].src.v4)
+ return 0;
+
+ if (test_bit(ATTR_ORIG_IPV4_DST, ct1->set) &&
+ test_bit(ATTR_ORIG_IPV4_DST, ct2->set) &&
+ ct1->tuple[__DIR_ORIG].dst.v4 !=
+ ct2->tuple[__DIR_ORIG].dst.v4)
+ return 0;
+
+ if (test_bit(ATTR_REPL_IPV4_SRC, ct1->set) &&
+ test_bit(ATTR_REPL_IPV4_SRC, ct2->set) &&
+ ct1->tuple[__DIR_REPL].src.v4 !=
+ ct2->tuple[__DIR_REPL].src.v4)
+ return 0;
+
+ if (test_bit(ATTR_REPL_IPV4_DST, ct1->set) &&
+ test_bit(ATTR_REPL_IPV4_DST, ct2->set) &&
+ ct1->tuple[__DIR_REPL].dst.v4 !=
+ ct2->tuple[__DIR_REPL].dst.v4)
+ return 0;
+
+ if (test_bit(ATTR_ORIG_IPV6_SRC, ct1->set) &&
+ test_bit(ATTR_ORIG_IPV6_SRC, ct2->set) &&
+ memcmp(&ct1->tuple[__DIR_ORIG].src.v6,
+ &ct2->tuple[__DIR_ORIG].src.v6,
+ sizeof(u_int32_t)*4) == 0)
+ return 0;
+
+ if (test_bit(ATTR_ORIG_IPV6_DST, ct1->set) &&
+ test_bit(ATTR_ORIG_IPV6_DST, ct2->set) &&
+ memcmp(&ct1->tuple[__DIR_ORIG].dst.v6,
+ &ct2->tuple[__DIR_ORIG].dst.v6,
+ sizeof(u_int32_t)*4) == 0)
+ return 0;
+
+ if (test_bit(ATTR_REPL_IPV6_SRC, ct1->set) &&
+ test_bit(ATTR_REPL_IPV6_SRC, ct2->set) &&
+ memcmp(&ct1->tuple[__DIR_REPL].src.v6,
+ &ct2->tuple[__DIR_REPL].src.v6,
+ sizeof(u_int32_t)*4) == 0)
+ return 0;
+
+ if (test_bit(ATTR_REPL_IPV6_DST, ct1->set) &&
+ test_bit(ATTR_REPL_IPV6_DST, ct2->set) &&
+ memcmp(&ct1->tuple[__DIR_REPL].dst.v6,
+ &ct2->tuple[__DIR_REPL].dst.v6,
+ sizeof(u_int32_t)*4) == 0)
+ return 0;
+
+ return 1;
+}
Deleted: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/libnetfilter_conntrack.c
===================================================================
--- trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c 2007-06-25 14:55:18 UTC (rev 6889)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/libnetfilter_conntrack.c 2007-07-28 12:31:57 UTC (rev 6963)
@@ -1,1307 +0,0 @@
-/*
- * (C) 2005-2006 by Pablo Neira Ayuso <pablo at netfilter.org>
- * Harald Welte <laforge at netfilter.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#include <stdio.h>
-#include <unistd.h>
-#include <getopt.h>
-#include <dlfcn.h>
-#include <stdlib.h>
-#include <signal.h>
-#include <errno.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include "linux_list.h"
-#include <libnfnetlink/libnfnetlink.h>
-#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
-#include <libnetfilter_conntrack/libnetfilter_conntrack_l3extensions.h>
-#include <libnetfilter_conntrack/libnetfilter_conntrack_extensions.h>
-
-#include "internal.h"
-
-#define NFCT_BUFSIZE 4096
-
-static char *lib_dir = LIBNETFILTER_CONNTRACK_DIR;
-static LIST_HEAD(proto_list);
-static LIST_HEAD(l3proto_list);
-static char *proto2str[IPPROTO_MAX] = {
- [IPPROTO_TCP] = "tcp",
- [IPPROTO_UDP] = "udp",
- [IPPROTO_ICMP] = "icmp",
- [IPPROTO_SCTP] = "sctp"
-};
-static char *l3proto2str[AF_MAX] = {
- [AF_INET] = "ipv4",
- [AF_INET6] = "ipv6"
-};
-static struct nfct_proto *findproto(char *name);
-static struct nfct_l3proto *findl3proto(char *name);
-
-/* handler used for nfnl_listen */
-static int callback_handler(struct sockaddr_nl *nladdr,
- struct nlmsghdr *n, void *arg)
-{
- struct nfct_handle *cth = (struct nfct_handle *) arg;
- int ret;
-
- if (NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK &&
- NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK_EXP) {
- nfnl_dump_packet(n, n->nlmsg_len, "callback_handler");
- return 0;
- }
-
- if (!cth)
- return -ENODEV;
-
- if (!cth->handler)
- return -ENODEV;
-
- ret = cth->handler(cth, n, NULL);
-
- return ret;
-}
-
-struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh,
- u_int8_t subsys_id,
- unsigned int subscriptions)
-{
- struct nfct_handle *cth;
-
- cth = (struct nfct_handle *) malloc(sizeof(struct nfct_handle));
- if (!cth)
- return NULL;
-
- memset(cth, 0, sizeof(*cth));
- cth->nfnlh = nfnlh;
-
- if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK) {
- cth->nfnlssh_ct = nfnl_subsys_open(cth->nfnlh,
- NFNL_SUBSYS_CTNETLINK,
- IPCTNL_MSG_MAX,
- subscriptions);
- if (!cth->nfnlssh_ct)
- goto out_free;
- }
-
- if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK_EXP) {
- cth->nfnlssh_exp = nfnl_subsys_open(cth->nfnlh,
- NFNL_SUBSYS_CTNETLINK_EXP,
- IPCTNL_MSG_EXP_MAX,
- subscriptions);
- if (!cth->nfnlssh_exp)
- goto out_free;
- }
-
- return cth;
-
-out_free:
- if (cth->nfnlssh_exp) {
- nfnl_subsys_close(cth->nfnlssh_exp);
- cth->nfnlssh_exp = NULL;
- }
- if (cth->nfnlssh_ct) {
- nfnl_subsys_close(cth->nfnlssh_ct);
- cth->nfnlssh_ct = NULL;
- }
- free(cth);
- return NULL;
-}
-
-struct nfct_handle *nfct_open(u_int8_t subsys_id, unsigned subscriptions)
-{
- struct nfnl_handle *nfnlh = nfnl_open();
- struct nfct_handle *nfcth;
-
- if (!nfnlh)
- return NULL;
-
- nfcth = nfct_open_nfnl(nfnlh, subsys_id, subscriptions);
- if (!nfcth)
- nfnl_close(nfnlh);
-
- return nfcth;
-}
-
-int nfct_close(struct nfct_handle *cth)
-{
- int err;
-
- if (cth->nfnlssh_exp) {
- nfnl_subsys_close(cth->nfnlssh_exp);
- cth->nfnlssh_exp = NULL;
- }
- if (cth->nfnlssh_ct) {
- nfnl_subsys_close(cth->nfnlssh_ct);
- cth->nfnlssh_ct = NULL;
- }
-
- /* required by the new API */
- cth->cb = NULL;
- free(cth->nfnl_cb.data);
-
- cth->nfnl_cb.call = NULL;
- cth->nfnl_cb.data = NULL;
- cth->nfnl_cb.attr_count = 0;
-
- err = nfnl_close(cth->nfnlh);
- free(cth);
-
- return err;
-}
-
-int nfct_fd(struct nfct_handle *cth)
-{
- return nfnl_fd(cth->nfnlh);
-}
-
-void nfct_register_callback(struct nfct_handle *cth, nfct_callback callback,
- void *data)
-{
- cth->callback = callback;
- cth->callback_data = data;
-}
-
-void nfct_unregister_callback(struct nfct_handle *cth)
-{
- cth->callback = NULL;
- cth->callback_data = NULL;
-}
-
-static void nfct_build_tuple_ip(struct nfnlhdr *req, int size,
- struct nfct_tuple *t)
-{
- struct nfattr *nest;
- struct nfct_l3proto *h;
-
- nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_IP);
-
- h = findl3proto(l3proto2str[t->l3protonum]);
- if (h && h->build_tuple_proto)
- h->build_tuple_proto(req, size, t);
-
- nfnl_nest_end(&req->nlh, nest);
-}
-
-static void nfct_build_tuple_proto(struct nfnlhdr *req, int size,
- struct nfct_tuple *t)
-{
- struct nfct_proto *h;
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_PROTO);
-
- nfnl_addattr_l(&req->nlh, size, CTA_PROTO_NUM, &t->protonum,
- sizeof(u_int8_t));
-
- h = findproto(proto2str[t->protonum]);
-
- if (h && h->build_tuple_proto)
- h->build_tuple_proto(req, size, t);
-
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void nfct_build_tuple(struct nfnlhdr *req, int size,
- struct nfct_tuple *t, int type)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, type);
-
- nfct_build_tuple_ip(req, size, t);
- nfct_build_tuple_proto(req, size, t);
-
- nfnl_nest_end(&req->nlh, nest);
-}
-
-static void nfct_build_protoinfo(struct nfnlhdr *req, int size,
- struct nfct_conntrack *ct)
-{
- struct nfattr *nest;
- struct nfct_proto *h;
-
- h = findproto(proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum]);
- if (h && h->build_protoinfo) {
- nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
- h->build_protoinfo(req, size, ct);
- nfnl_nest_end(&req->nlh, nest);
- }
-}
-
-static void nfct_build_protonat(struct nfnlhdr *req, int size,
- struct nfct_conntrack *ct)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_NAT_PROTO);
-
- switch (ct->tuple[NFCT_DIR_ORIGINAL].protonum) {
-#if 0
- case IPPROTO_TCP:
- nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_TCP_MIN,
- &ct->nat.l4min.tcp.port, sizeof(u_int16_t));
- nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_TCP_MAX,
- &ct->nat.l4max.tcp.port, sizeof(u_int16_t));
- break;
- case IPPROTO_UDP:
- nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_UDP_MIN,
- &ct->nat.l4min.udp.port, sizeof(u_int16_t));
- nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_UDP_MAX,
- &ct->nat.l4max.udp.port, sizeof(u_int16_t));
- break;
-#endif
- }
- nfnl_nest_end(&req->nlh, nest);
-}
-
-static void nfct_build_nat(struct nfnlhdr *req, int size,
- struct nfct_conntrack *ct)
-{
- struct nfattr *nest;
-
- nest = nfnl_nest(&req->nlh, size, CTA_NAT);
-
- nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP,
- &ct->nat.min_ip, sizeof(u_int32_t));
-
- if (ct->nat.min_ip != ct->nat.max_ip)
- nfnl_addattr_l(&req->nlh, size, CTA_NAT_MAXIP,
- &ct->nat.max_ip, sizeof(u_int32_t));
-
- if (ct->nat.l4min.all != ct->nat.l4max.all)
- nfct_build_protonat(req, size, ct);
-
- nfnl_nest_end(&req->nlh, nest);
-}
-
-void nfct_dump_tuple(struct nfct_tuple *tp)
-{
- struct in_addr src = { .s_addr = tp->src.v4 };
- struct in_addr dst = { .s_addr = tp->dst.v4 };
-
- fprintf(stdout, "tuple %p: %u %s:%hu -> ", tp, tp->protonum,
- inet_ntoa(src),
- ntohs(tp->l4src.all));
-
- fprintf(stdout, "%s:%hu\n", inet_ntoa(dst), ntohs(tp->l4dst.all));
-}
-
-static struct nfct_proto *findproto(char *name)
-{
- struct list_head *i;
- struct nfct_proto *cur = NULL, *handler = NULL;
-
- if (!name)
- return handler;
-
- lib_dir = getenv("LIBNETFILTER_CONNTRACK_DIR");
- if (!lib_dir)
- lib_dir = LIBNETFILTER_CONNTRACK_DIR;
-
- list_for_each(i, &proto_list) {
- cur = (struct nfct_proto *) i;
- if (strcmp(cur->name, name) == 0) {
- handler = cur;
- break;
- }
- }
-
- if (!handler) {
- char path[sizeof("nfct_proto_.so") + strlen(VERSION)
- + strlen(name) + strlen(lib_dir)];
- sprintf(path, "%s/nfct_proto_%s-%s.so", lib_dir, name, VERSION);
- if (dlopen(path, RTLD_NOW))
- handler = findproto(name);
- else
- fprintf(stderr, "%s\n", dlerror());
- }
-
- return handler;
-}
-
-static struct nfct_l3proto *findl3proto(char *name)
-{
- struct list_head *i;
- struct nfct_l3proto *cur = NULL, *handler = NULL;
-
- if (!name)
- return handler;
-
- lib_dir = getenv("LIBNETFILTER_CONNTRACK_DIR");
- if (!lib_dir)
- lib_dir = LIBNETFILTER_CONNTRACK_DIR;
-
- list_for_each(i, &l3proto_list) {
- cur = (struct nfct_l3proto *) i;
- if (strcmp(cur->name, name) == 0) {
- handler = cur;
- break;
- }
- }
-
- if (!handler) {
- char path[sizeof("nfct_l3proto_.so") + strlen(VERSION)
- + strlen(name) + strlen(lib_dir)];
- sprintf(path, "%s/nfct_l3proto_%s-%s.so",lib_dir,name,VERSION);
- if (dlopen(path, RTLD_NOW))
- handler = findl3proto(name);
- else
- fprintf(stderr, "%s\n", dlerror());
- }
-
- return handler;
-}
-
-int nfct_sprintf_status_assured(char *buf, struct nfct_conntrack *ct)
-{
- int size = 0;
-
- if (ct->status & IPS_ASSURED)
- size = sprintf(buf, "[ASSURED] ");
-
- return size;
-}
-
-int nfct_sprintf_status_seen_reply(char *buf, struct nfct_conntrack *ct)
-{
- int size = 0;
-
- if (!(ct->status & IPS_SEEN_REPLY))
- size = sprintf(buf, "[UNREPLIED] ");
-
- return size;
-}
-
-static void parse_ip(struct nfattr *attr, struct nfct_tuple *tuple)
-{
- struct nfattr *tb[CTA_IP_MAX];
- struct nfct_l3proto *h;
-
- nfnl_parse_nested(tb, CTA_IP_MAX, attr);
- h = findl3proto(l3proto2str[tuple->l3protonum]);
- if (h && h->parse_proto)
- h->parse_proto(tb, tuple);
-}
-
-static void parse_proto(struct nfattr *attr, struct nfct_tuple *tuple)
-{
- struct nfattr *tb[CTA_PROTO_MAX];
- struct nfct_proto *h;
-
- nfnl_parse_nested(tb, CTA_PROTO_MAX, attr);
- if (tb[CTA_PROTO_NUM-1])
- tuple->protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
-
- h = findproto(proto2str[tuple->protonum]);
- if (h && h->parse_proto)
- h->parse_proto(tb, tuple);
-}
-
-static void parse_tuple(struct nfattr *attr, struct nfct_tuple *tuple)
-{
- struct nfattr *tb[CTA_TUPLE_MAX];
-
- nfnl_parse_nested(tb, CTA_TUPLE_MAX, attr);
-
- if (tb[CTA_TUPLE_IP-1])
- parse_ip(tb[CTA_TUPLE_IP-1], tuple);
- if (tb[CTA_TUPLE_PROTO-1])
- parse_proto(tb[CTA_TUPLE_PROTO-1], tuple);
-}
-
-static void parse_mask(struct nfattr *attr, struct nfct_tuple *tuple,
- u_int8_t l3protonum, u_int16_t protonum)
-{
- struct nfattr *cda[CTA_TUPLE_MAX];
-
- nfnl_parse_nested(cda, CTA_TUPLE_MAX, attr);
-
- if (cda[CTA_TUPLE_IP-1]) {
- struct nfattr *tb[CTA_IP_MAX];
- struct nfct_l3proto *h;
-
- nfnl_parse_nested(tb, CTA_IP_MAX, cda[CTA_TUPLE_IP-1]);
- h = findl3proto(l3proto2str[l3protonum]);
- if (h && h->parse_proto)
- h->parse_proto(tb, tuple);
- }
- if (cda[CTA_TUPLE_PROTO-1]) {
- struct nfattr *tb[CTA_PROTO_MAX];
- struct nfct_proto *h;
-
- nfnl_parse_nested(tb, CTA_PROTO_MAX, cda[CTA_TUPLE_PROTO-1]);
- if (tb[CTA_PROTO_NUM-1])
- tuple->protonum =
- *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
-
- h = findproto(proto2str[protonum]);
- if (h && h->parse_proto)
- h->parse_proto(tb, tuple);
- }
-}
-
-static void parse_protoinfo(struct nfattr *attr, struct nfct_conntrack *ct)
-{
- struct nfattr *tb[CTA_PROTOINFO_MAX];
- struct nfct_proto *h;
-
- nfnl_parse_nested(tb,CTA_PROTOINFO_MAX, attr);
-
- h = findproto(proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum]);
- if (h && h->parse_protoinfo)
- h->parse_protoinfo(tb, ct);
-}
-
-static void nfct_parse_counters(struct nfattr *attr,
- struct nfct_conntrack *ct,
- enum ctattr_type parent)
-{
- struct nfattr *tb[CTA_COUNTERS_MAX];
- int dir = (parent == CTA_COUNTERS_ORIG ? NFCT_DIR_REPLY
- : NFCT_DIR_ORIGINAL);
-
- nfnl_parse_nested(tb, CTA_COUNTERS_MAX, attr);
- if (tb[CTA_COUNTERS_PACKETS-1])
- ct->counters[dir].packets
- = __be64_to_cpu(*(u_int64_t *)
- NFA_DATA(tb[CTA_COUNTERS_PACKETS-1]));
- if (tb[CTA_COUNTERS_BYTES-1])
- ct->counters[dir].bytes
- = __be64_to_cpu(*(u_int64_t *)
- NFA_DATA(tb[CTA_COUNTERS_BYTES-1]));
- if (tb[CTA_COUNTERS32_PACKETS-1])
- ct->counters[dir].packets
- = ntohl(*(u_int32_t *)
- NFA_DATA(tb[CTA_COUNTERS32_PACKETS-1]));
- if (tb[CTA_COUNTERS32_BYTES-1])
- ct->counters[dir].bytes
- = ntohl(*(u_int32_t *)
- NFA_DATA(tb[CTA_COUNTERS32_BYTES-1]));
-}
-
-static char *msgtype[] = {"[UNKNOWN]", "[NEW]", "[UPDATE]", "[DESTROY]"};
-
-static int typemsg2enum(u_int16_t type, u_int16_t flags)
-{
- int ret = NFCT_MSG_UNKNOWN;
-
- if (type == IPCTNL_MSG_CT_NEW) {
- if (flags & (NLM_F_CREATE|NLM_F_EXCL))
- ret = NFCT_MSG_NEW;
- else
- ret = NFCT_MSG_UPDATE;
- } else if (type == IPCTNL_MSG_CT_DELETE)
- ret = NFCT_MSG_DESTROY;
-
- return ret;
-}
-
-static int nfct_conntrack_netlink_handler(struct nfct_handle *cth,
- struct nlmsghdr *nlh, void *arg)
-{
- struct nfct_conntrack ct;
- unsigned int flags = 0;
- struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
- int type = NFNL_MSG_TYPE(nlh->nlmsg_type), ret = 0;
- int len = nlh->nlmsg_len;
- struct nfattr *cda[CTA_MAX];
-
- len -= NLMSG_LENGTH(sizeof(struct nfgenmsg));
- if (len < 0)
- return -EINVAL;
-
- memset(&ct, 0, sizeof(struct nfct_conntrack));
-
- ct.tuple[NFCT_DIR_ORIGINAL].l3protonum = nfhdr->nfgen_family;
- ct.tuple[NFCT_DIR_REPLY].l3protonum = nfhdr->nfgen_family;
-
- nfnl_parse_attr(cda, CTA_MAX, NFA_DATA(nfhdr), len);
-
- if (cda[CTA_TUPLE_ORIG-1])
- parse_tuple(cda[CTA_TUPLE_ORIG-1],
- &ct.tuple[NFCT_DIR_ORIGINAL]);
-
- if (cda[CTA_TUPLE_REPLY-1])
- parse_tuple(cda[CTA_TUPLE_REPLY-1],
- &ct.tuple[NFCT_DIR_REPLY]);
-
- if (cda[CTA_STATUS-1]) {
- ct.status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]));
- flags |= NFCT_STATUS;
- }
-
- if (cda[CTA_PROTOINFO-1]) {
- parse_protoinfo(cda[CTA_PROTOINFO-1], &ct);
- flags |= NFCT_PROTOINFO;
- }
-
- if (cda[CTA_TIMEOUT-1]) {
- ct.timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
- flags |= NFCT_TIMEOUT;
- }
-
- if (cda[CTA_MARK-1]) {
- ct.mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
- flags |= NFCT_MARK;
- }
-
- if (cda[CTA_COUNTERS_ORIG-1]) {
- nfct_parse_counters(cda[CTA_COUNTERS_ORIG-1], &ct,
- NFA_TYPE(cda[CTA_COUNTERS_ORIG-1])-1);
- flags |= NFCT_COUNTERS_ORIG;
- }
-
- if (cda[CTA_COUNTERS_REPLY-1]) {
- nfct_parse_counters(cda[CTA_COUNTERS_REPLY-1], &ct,
- NFA_TYPE(cda[CTA_COUNTERS_REPLY-1])-1);
- flags |= NFCT_COUNTERS_RPLY;
- }
-
- if (cda[CTA_USE-1]) {
- ct.use = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_USE-1]));
- flags |= NFCT_USE;
- }
-
- if (cda[CTA_ID-1]) {
- ct.id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_ID-1]));
- flags |= NFCT_ID;
- }
-
- if (cth->callback)
- ret = cth->callback((void *) &ct, flags,
- typemsg2enum(type, nlh->nlmsg_flags),
- cth->callback_data);
-
- return ret;
-}
-
-int nfct_sprintf_protocol(char *buf, struct nfct_conntrack *ct)
-{
- return (sprintf(buf, "%-8s %u ",
- proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum] == NULL ?
- "unknown" : proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum],
- ct->tuple[NFCT_DIR_ORIGINAL].protonum));
-}
-
-int nfct_sprintf_timeout(char *buf, struct nfct_conntrack *ct)
-{
- return sprintf(buf, "%u ", ct->timeout);
-}
-
-int nfct_sprintf_protoinfo(char *buf, struct nfct_conntrack *ct)
-{
- int size = 0;
- struct nfct_proto *h = NULL;
-
- h = findproto(proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum]);
- if (h && h->print_protoinfo)
- size += h->print_protoinfo(buf+size, &ct->protoinfo);
-
- return size;
-}
-
-int nfct_sprintf_address(char *buf, struct nfct_tuple *t)
-{
- int size = 0;
- struct nfct_l3proto *h;
-
- h = findl3proto(l3proto2str[t->l3protonum]);
- if (h && h->print_proto)
- size += h->print_proto(buf, t);
-
- return size;
-}
-
-int nfct_sprintf_proto(char *buf, struct nfct_tuple *t)
-{
- int size = 0;
- struct nfct_proto *h = NULL;
-
- h = findproto(proto2str[t->protonum]);
- if (h && h->print_proto)
- size += h->print_proto(buf, t);
-
- return size;
-}
-
-int nfct_sprintf_counters(char *buf, struct nfct_conntrack *ct, int dir)
-{
- return (sprintf(buf, "packets=%llu bytes=%llu ",
- (unsigned long long) ct->counters[dir].packets,
- (unsigned long long) ct->counters[dir].bytes));
-}
-
-int nfct_sprintf_mark(char *buf, struct nfct_conntrack *ct)
-{
- return (sprintf(buf, "mark=%u ", ct->mark));
-}
-
-int nfct_sprintf_use(char *buf, struct nfct_conntrack *ct)
-{
- return (sprintf(buf, "use=%u ", ct->use));
-}
-
-int nfct_sprintf_id(char *buf, u_int32_t id)
-{
- return (sprintf(buf, "id=%u ", id));
-}
-
-int nfct_sprintf_conntrack(char *buf, struct nfct_conntrack *ct,
- unsigned int flags)
-{
- int size = 0;
-
- size += nfct_sprintf_protocol(buf, ct);
-
- if (flags & NFCT_TIMEOUT)
- size += nfct_sprintf_timeout(buf+size, ct);
-
- if (flags & NFCT_PROTOINFO)
- size += nfct_sprintf_protoinfo(buf+size, ct);
-
- size += nfct_sprintf_address(buf+size, &ct->tuple[NFCT_DIR_ORIGINAL]);
- size += nfct_sprintf_proto(buf+size, &ct->tuple[NFCT_DIR_ORIGINAL]);
-
- if (flags & NFCT_COUNTERS_ORIG)
- size += nfct_sprintf_counters(buf+size, ct, NFCT_DIR_ORIGINAL);
-
- if (flags & NFCT_STATUS)
- size += nfct_sprintf_status_seen_reply(buf+size, ct);
-
- size += nfct_sprintf_address(buf+size, &ct->tuple[NFCT_DIR_REPLY]);
- size += nfct_sprintf_proto(buf+size, &ct->tuple[NFCT_DIR_REPLY]);
-
- if (flags & NFCT_COUNTERS_RPLY)
- size += nfct_sprintf_counters(buf+size, ct, NFCT_DIR_REPLY);
-
- if (flags & NFCT_STATUS)
- size += nfct_sprintf_status_assured(buf+size, ct);
-
- if (flags & NFCT_MARK)
- size += nfct_sprintf_mark(buf+size, ct);
-
- if (flags & NFCT_USE)
- size += nfct_sprintf_use(buf+size, ct);
-
- /* Delete the last blank space */
- size--;
-
- return size;
-}
-
-int nfct_sprintf_conntrack_id(char *buf, struct nfct_conntrack *ct,
- unsigned int flags)
-{
- int size;
-
- /* add a blank space, that's why the add 1 to the size */
- size = nfct_sprintf_conntrack(buf, ct, flags) + 1;
- if (flags & NFCT_ID)
- size += nfct_sprintf_id(buf+size, ct->id);
-
- /* Delete the last blank space */
- return --size;
-}
-
-int nfct_default_conntrack_display(void *arg, unsigned int flags, int type,
- void *data)
-{
- char buf[512];
- int size;
- struct nfct_conntrack_compare *cmp = data;
-
- if (cmp && !nfct_conntrack_compare(cmp->ct, arg, cmp))
- return 0;
-
- memset(buf, 0, sizeof(buf));
- size = nfct_sprintf_conntrack(buf, arg, flags);
- sprintf(buf+size, "\n");
- fprintf(stdout, buf);
-
- return 0;
-}
-
-int nfct_default_conntrack_display_id(void *arg, unsigned int flags, int type,
- void *data)
-{
- char buf[512];
- int size;
- struct nfct_conntrack_compare *cmp = data;
-
- if (cmp && !nfct_conntrack_compare(cmp->ct, arg, cmp))
- return 0;
-
- memset(buf, 0, sizeof(buf));
- size = nfct_sprintf_conntrack_id(buf, arg, flags);
- sprintf(buf+size, "\n");
- fprintf(stdout, buf);
-
- return 0;
-}
-
-int nfct_default_conntrack_event_display(void *arg, unsigned int flags,
- int type, void *data)
-{
- char buf[512];
- int size;
- struct nfct_conntrack_compare *cmp = data;
-
- if (cmp && !nfct_conntrack_compare(cmp->ct, arg, cmp))
- return 0;
-
- memset(buf, 0, sizeof(buf));
- size = sprintf(buf, "%9s ", msgtype[type]);
- size += nfct_sprintf_conntrack_id(buf + size, arg, flags);
- sprintf(buf+size, "\n");
- fprintf(stdout, buf);
- fflush(stdout);
-
- return 0;
-}
-
-int nfct_sprintf_expect_proto(char *buf, struct nfct_expect *exp)
-{
- return(sprintf(buf, "%u proto=%d ", exp->timeout,
- exp->tuple.protonum));
-}
-
-int nfct_sprintf_expect(char *buf, struct nfct_expect *exp)
-{
- int size = 0;
-
- size = nfct_sprintf_expect_proto(buf, exp);
- size += nfct_sprintf_address(buf+size, &exp->tuple);
- size += nfct_sprintf_proto(buf+size, &exp->tuple);
-
- /* remove last blank space */
- return --size;
-}
-
-int nfct_sprintf_expect_id(char *buf, struct nfct_expect *exp)
-{
- int size = 0;
-
- /* add a blank space, that's why the add 1 to the size */
- size = nfct_sprintf_expect(buf, exp) + 1;
- size += nfct_sprintf_id(buf+size, exp->id);
-
- /* remove last blank space */
- return --size;
-}
-
-int nfct_default_expect_display(void *arg, unsigned int flags, int type,
- void *data)
-{
- char buf[256];
- int size = 0;
-
- memset(buf, 0, sizeof(buf));
- size = nfct_sprintf_expect(buf, arg);
- sprintf(buf+size, "\n");
- fprintf(stdout, buf);
-
- return 0;
-}
-
-int nfct_default_expect_display_id(void *arg, unsigned int flags, int type,
- void *data)
-{
- char buf[256];
- int size = 0;
-
- size = nfct_sprintf_expect_id(buf, arg);
- sprintf(buf+size, "\n");
- fprintf(stdout, buf);
-
- return 0;
-}
-
-static int nfct_expect_netlink_handler(struct nfct_handle *cth,
- struct nlmsghdr *nlh, void *arg)
-{
- struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
- struct nfct_expect exp;
- int type = NFNL_MSG_TYPE(nlh->nlmsg_type), ret = 0;
- int len = nlh->nlmsg_len;
- struct nfattr *cda[CTA_EXPECT_MAX];
-
- len -= NLMSG_LENGTH(sizeof(struct nfgenmsg));
- if (len < 0)
- return -EINVAL;
-
- memset(&exp, 0, sizeof(struct nfct_expect));
-
- exp.tuple.l3protonum = nfhdr->nfgen_family;
-
- nfnl_parse_attr(cda, CTA_EXPECT_MAX, NFA_DATA(nfhdr), len);
-
- if (cda[CTA_EXPECT_TUPLE-1])
- parse_tuple(cda[CTA_EXPECT_TUPLE-1], &exp.tuple);
-
- if (cda[CTA_EXPECT_MASK-1])
- parse_mask(cda[CTA_EXPECT_MASK-1], &exp.mask,
- exp.tuple.l3protonum, exp.tuple.protonum);
-
- if (cda[CTA_EXPECT_TIMEOUT-1])
- exp.timeout = ntohl(*(u_int32_t *)
- NFA_DATA(cda[CTA_EXPECT_TIMEOUT-1]));
-
- if (cda[CTA_EXPECT_ID-1])
- exp.id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]));
-
- if (cth->callback)
- ret = cth->callback((void *)&exp, 0,
- typemsg2enum(type, nlh->nlmsg_flags),
- cth->callback_data);
-
- return 0;
-}
-
-struct nfct_conntrack *
-nfct_conntrack_alloc(struct nfct_tuple *orig, struct nfct_tuple *reply,
- u_int32_t timeout, union nfct_protoinfo *proto,
- u_int32_t status, u_int32_t mark,
- u_int32_t id, struct nfct_nat *range)
-{
- struct nfct_conntrack *ct;
-
- ct = malloc(sizeof(struct nfct_conntrack));
- if (!ct)
- return NULL;
- memset(ct, 0, sizeof(struct nfct_conntrack));
-
- ct->tuple[NFCT_DIR_ORIGINAL] = *orig;
- ct->tuple[NFCT_DIR_REPLY] = *reply;
- ct->timeout = timeout;
- ct->status = status;
- ct->protoinfo = *proto;
- ct->mark = mark;
- if (id != NFCT_ANY_ID)
- ct->id = id;
- if (range)
- ct->nat = *range;
-
- return ct;
-}
-
-void nfct_conntrack_free(struct nfct_conntrack *ct)
-{
- free(ct);
-}
-
-#define L3PROTONUM(ct) ct->tuple[NFCT_DIR_ORIGINAL].l3protonum
-#define L4PROTONUM(ct) ct->tuple[NFCT_DIR_ORIGINAL].protonum
-
-int nfct_conntrack_compare(struct nfct_conntrack *ct1,
- struct nfct_conntrack *ct2,
- struct nfct_conntrack_compare *cmp)
-{
- struct nfct_l3proto *l3proto;
- struct nfct_proto *proto;
- unsigned int l3flags = cmp->l3flags;
- unsigned int l4flags = cmp->l4flags;
- unsigned int flags = cmp->flags;
-
- if ((flags & NFCT_MARK) && (ct1->mark != ct2->mark))
- return 0;
-
- if (l3flags) {
- if (ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum != AF_UNSPEC &&
- ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum != AF_UNSPEC &&
- ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum !=
- ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum)
- return 0;
- if (ct1->tuple[NFCT_DIR_REPLY].l3protonum != AF_UNSPEC &&
- ct2->tuple[NFCT_DIR_REPLY].l3protonum != AF_UNSPEC &&
- ct1->tuple[NFCT_DIR_REPLY].l3protonum !=
- ct2->tuple[NFCT_DIR_REPLY].l3protonum)
- return 0;
- l3proto = findl3proto(l3proto2str[L3PROTONUM(ct1)]);
- if (l3proto && !l3proto->compare(ct1, ct2, l3flags))
- return 0;
- }
-
- if (l4flags) {
- if (ct1->tuple[NFCT_DIR_ORIGINAL].protonum != 0 &&
- ct2->tuple[NFCT_DIR_ORIGINAL].protonum != 0 &&
- ct1->tuple[NFCT_DIR_ORIGINAL].protonum !=
- ct2->tuple[NFCT_DIR_ORIGINAL].protonum)
- return 0;
- if (ct1->tuple[NFCT_DIR_REPLY].protonum != 0 &&
- ct2->tuple[NFCT_DIR_REPLY].protonum != 0 &&
- ct1->tuple[NFCT_DIR_REPLY].protonum !=
- ct2->tuple[NFCT_DIR_REPLY].protonum)
- return 0;
- proto = findproto(proto2str[L4PROTONUM(ct1)]);
- if (proto && !proto->compare(ct1, ct2, l4flags))
- return 0;
- }
-
- return 1;
-}
-
-int nfct_create_conntrack(struct nfct_handle *cth, struct nfct_conntrack *ct)
-{
- struct nfnlhdr *req;
- char buf[NFCT_BUFSIZE];
- u_int32_t status = htonl(ct->status | IPS_CONFIRMED);
- u_int32_t timeout = htonl(ct->timeout);
- u_int32_t mark = htonl(ct->mark);
- u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
-
- req = (void *) buf;
-
- memset(buf, 0, sizeof(buf));
-
- nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0, l3num, 0,
- IPCTNL_MSG_CT_NEW,
- NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL);
-
- nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_ORIGINAL],
- CTA_TUPLE_ORIG);
- nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_REPLY],
- CTA_TUPLE_REPLY);
-
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_STATUS, &status,
- sizeof(u_int32_t));
-
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_TIMEOUT, &timeout,
- sizeof(u_int32_t));
-
- if (ct->mark != 0)
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_MARK, &mark,
- sizeof(u_int32_t));
-
- nfct_build_protoinfo(req, sizeof(buf), ct);
- if (ct->nat.min_ip != 0)
- nfct_build_nat(req, sizeof(buf), ct);
-
- return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
-}
-
-int nfct_update_conntrack(struct nfct_handle *cth, struct nfct_conntrack *ct)
-{
- struct nfnlhdr *req;
- char buf[NFCT_BUFSIZE];
- u_int32_t status = htonl(ct->status | IPS_CONFIRMED);
- u_int32_t timeout = htonl(ct->timeout);
- u_int32_t id = htonl(ct->id);
- u_int32_t mark = htonl(ct->mark);
- u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
-
- req = (void *) &buf;
- memset(&buf, 0, sizeof(buf));
-
- nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0, l3num, 0,
- IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_ACK);
-
- nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_ORIGINAL],
- CTA_TUPLE_ORIG);
- nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_REPLY],
- CTA_TUPLE_REPLY);
-
- if (ct->status != 0)
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_STATUS, &status,
- sizeof(u_int32_t));
-
- if (ct->timeout != 0)
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_TIMEOUT, &timeout,
- sizeof(u_int32_t));
-
- if (ct->mark != 0)
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_MARK, &mark,
- sizeof(u_int32_t));
-
- if (ct->id != NFCT_ANY_ID)
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ID, &id,
- sizeof(u_int32_t));
-
- nfct_build_protoinfo(req, sizeof(buf), ct);
-
- return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
-}
-
-int nfct_delete_conntrack(struct nfct_handle *cth, struct nfct_tuple *tuple,
- int dir, u_int32_t id)
-{
- struct nfnlhdr *req;
- char buf[NFCT_BUFSIZE];
- int type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG;
- u_int8_t l3num = tuple->l3protonum;
-
- req = (void *) &buf;
- memset(&buf, 0, sizeof(buf));
-
- nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0,
- l3num, 0, IPCTNL_MSG_CT_DELETE,
- NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
-
- nfct_build_tuple(req, sizeof(buf), tuple, type);
-
- if (id != NFCT_ANY_ID) {
- id = htonl(id); /* to network byte order */
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ID, &id,
- sizeof(u_int32_t));
- }
-
- return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
-}
-
-int nfct_get_conntrack(struct nfct_handle *cth, struct nfct_tuple *tuple,
- int dir, u_int32_t id)
-{
- int err;
- struct nfnlhdr *req;
- char buf[NFCT_BUFSIZE];
- int type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG;
- u_int8_t l3num = tuple->l3protonum;
-
- cth->handler = nfct_conntrack_netlink_handler;
-
- memset(&buf, 0, sizeof(buf));
- req = (void *) &buf;
-
- nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0,
- l3num, 0, IPCTNL_MSG_CT_GET,
- NLM_F_REQUEST|NLM_F_ACK);
-
- nfct_build_tuple(req, sizeof(buf), tuple, type);
-
- if (id != NFCT_ANY_ID) {
- id = htonl(id); /* to network byte order */
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ID, &id,
- sizeof(u_int32_t));
- }
-
- err = nfnl_send(cth->nfnlh, &req->nlh);
- if (err < 0)
- return err;
-
- return nfnl_listen(cth->nfnlh, &callback_handler, cth);
-}
-
-static int __nfct_dump_conntrack_table(struct nfct_handle *cth, int zero,
- int family)
-{
- int err, msg;
- struct nfnlhdr req;
-
- memset(&req, 0, sizeof(req));
- cth->handler = nfct_conntrack_netlink_handler;
-
- if (zero)
- msg = IPCTNL_MSG_CT_GET_CTRZERO;
- else
- msg = IPCTNL_MSG_CT_GET;
-
- nfnl_fill_hdr(cth->nfnlssh_ct, &req.nlh, 0, family, 0,
- msg, NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_DUMP);
-
- err = nfnl_send(cth->nfnlh, &req.nlh);
- if (err < 0)
- return err;
-
- return nfnl_listen(cth->nfnlh, &callback_handler, cth);
-}
-
-int nfct_dump_conntrack_table(struct nfct_handle *cth, int family)
-{
- return(__nfct_dump_conntrack_table(cth, 0, family));
-}
-
-int nfct_dump_conntrack_table_reset_counters(struct nfct_handle *cth,
- int family)
-{
- return(__nfct_dump_conntrack_table(cth, 1, family));
-}
-
-int nfct_event_conntrack(struct nfct_handle *cth)
-{
- cth->handler = nfct_conntrack_netlink_handler;
- return nfnl_listen(cth->nfnlh, &callback_handler, cth);
-}
-
-void nfct_register_proto(struct nfct_proto *h)
-{
- if (strcmp(h->version, VERSION) != 0) {
- fprintf(stderr, "plugin `%s': version %s (I'm %s)\n",
- h->name, h->version, VERSION);
- exit(1);
- }
- list_add(&h->head, &proto_list);
-}
-
-void nfct_register_l3proto(struct nfct_l3proto *h)
-{
- if (strcmp(h->version, VERSION) != 0) {
- fprintf(stderr, "plugin `%s': version %s (I'm %s)\n",
- h->name, h->version, VERSION);
- exit(1);
- }
- list_add(&h->head, &l3proto_list);
-}
-
-int nfct_dump_expect_list(struct nfct_handle *cth, int family)
-{
- int err;
- struct nfnlhdr req;
-
- memset(&req, 0, sizeof(req));
-
- cth->handler = nfct_expect_netlink_handler;
- nfnl_fill_hdr(cth->nfnlssh_exp, &req.nlh, 0, family, 0,
- IPCTNL_MSG_EXP_GET, NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST);
-
- err = nfnl_send(cth->nfnlh, &req.nlh);
- if (err < 0)
- return err;
-
- return nfnl_listen(cth->nfnlh, &callback_handler, cth);
-}
-
-int nfct_flush_conntrack_table(struct nfct_handle *cth, int family)
-{
- struct nfnlhdr req;
-
- memset(&req, 0, sizeof(req));
-
- nfnl_fill_hdr(cth->nfnlssh_ct, (struct nlmsghdr *) &req,
- 0, family, 0, IPCTNL_MSG_CT_DELETE,
- NLM_F_REQUEST|NLM_F_ACK);
-
- return nfnl_talk(cth->nfnlh, &req.nlh, 0, 0, NULL, NULL, NULL);
-}
-
-int nfct_get_expectation(struct nfct_handle *cth, struct nfct_tuple *tuple,
- u_int32_t id)
-{
- int err;
- struct nfnlhdr *req;
- char buf[NFCT_BUFSIZE];
- u_int8_t l3num = tuple->l3protonum;
-
- memset(&buf, 0, sizeof(buf));
- req = (void *) &buf;
-
- nfnl_fill_hdr(cth->nfnlssh_exp, &req->nlh, 0, l3num, 0,
- IPCTNL_MSG_EXP_GET,
- NLM_F_REQUEST|NLM_F_ACK);
-
- cth->handler = nfct_expect_netlink_handler;
- nfct_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER);
-
- if (id != NFCT_ANY_ID)
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_ID, &id,
- sizeof(u_int32_t));
-
- err = nfnl_send(cth->nfnlh, &req->nlh);
- if (err < 0)
- return err;
-
- return nfnl_listen(cth->nfnlh, &callback_handler, cth);
-}
-
-struct nfct_expect *
-nfct_expect_alloc(struct nfct_tuple *master, struct nfct_tuple *tuple,
- struct nfct_tuple *mask, u_int32_t timeout,
- u_int32_t id)
-{
- struct nfct_expect *exp;
-
- exp = malloc(sizeof(struct nfct_expect));
- if (!exp)
- return NULL;
- memset(exp, 0, sizeof(struct nfct_expect));
-
- exp->master = *master;
- exp->tuple = *tuple;
- exp->mask = *mask;
- exp->timeout = timeout;
- if (id != NFCT_ANY_ID)
- exp->id = htonl(id);
-
- return exp;
-}
-
-void nfct_expect_free(struct nfct_expect *exp)
-{
- free(exp);
-}
-
-int nfct_create_expectation(struct nfct_handle *cth, struct nfct_expect *exp)
-{
- struct nfnlhdr *req;
- char buf[NFCT_BUFSIZE];
- req = (void *) &buf;
- u_int8_t l3num = exp->tuple.l3protonum;
- u_int32_t timeout;
- u_int16_t queuenr;
-
- memset(&buf, 0, sizeof(buf));
-
- nfnl_fill_hdr(cth->nfnlssh_exp, &req->nlh, 0, l3num, 0,
- IPCTNL_MSG_EXP_NEW,
- NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK);
-
- nfct_build_tuple(req, sizeof(buf), &exp->master, CTA_EXPECT_MASTER);
- nfct_build_tuple(req, sizeof(buf), &exp->tuple, CTA_EXPECT_TUPLE);
- nfct_build_tuple(req, sizeof(buf), &exp->mask, CTA_EXPECT_MASK);
-
- timeout = htonl(exp->timeout);
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_TIMEOUT,
- &timeout, sizeof(u_int32_t));
-
- queuenr = htons(exp->expectfn_queue_id);
- if (queuenr)
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_QUEUENR,
- &queuenr, sizeof(u_int16_t));
-
- return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
-}
-
-int nfct_delete_expectation(struct nfct_handle *cth, struct nfct_tuple *tuple,
- u_int32_t id)
-{
- struct nfnlhdr *req;
- char buf[NFCT_BUFSIZE];
- u_int8_t l3num = tuple->l3protonum;
-
- memset(&buf, 0, sizeof(buf));
- req = (void *) &buf;
-
- nfnl_fill_hdr(cth->nfnlssh_exp, &req->nlh, 0, l3num,
- 0, IPCTNL_MSG_EXP_DELETE,
- NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
-
- nfct_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER);
-
- if (id != NFCT_ANY_ID)
- nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_ID, &id,
- sizeof(u_int32_t));
-
- return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
-}
-
-int nfct_event_expectation(struct nfct_handle *cth)
-{
- cth->handler = nfct_expect_netlink_handler;
- return nfnl_listen(cth->nfnlh, &callback_handler, cth);
-}
-
-int nfct_flush_expectation_table(struct nfct_handle *cth, int family)
-{
- struct nfnlhdr req;
-
- memset(&req, 0, sizeof(req));
-
- nfnl_fill_hdr(cth->nfnlssh_exp, (struct nlmsghdr *) &req,
- 0, family, 0, IPCTNL_MSG_EXP_DELETE,
- NLM_F_REQUEST|NLM_F_ACK);
-
- return nfnl_talk(cth->nfnlh, &req.nlh, 0, 0, NULL, NULL, NULL);
-}
Copied: tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/libnetfilter_conntrack.c (from rev 6902, trunk/libnetfilter_conntrack/src/libnetfilter_conntrack.c)
===================================================================
--- tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/libnetfilter_conntrack.c (rev 0)
+++ tags/libnetfilter_conntrack/libnetfilter_conntrack-0.0.81/src/libnetfilter_conntrack.c 2007-07-28 12:31:57 UTC (rev 6963)
@@ -0,0 +1,1312 @@
+/*
+ * (C) 2005-2006 by Pablo Neira Ayuso <pablo at netfilter.org>
+ * Harald Welte <laforge at netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include <string.h>
+#include <arpa/inet.h>
+#include "linux_list.h"
+#include <libnfnetlink/libnfnetlink.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_l3extensions.h>
+#include <libnetfilter_conntrack/libnetfilter_conntrack_extensions.h>
+
+#include "internal.h"
+
+#define NFCT_BUFSIZE 4096
+
+static char *lib_dir = LIBNETFILTER_CONNTRACK_DIR;
+static LIST_HEAD(proto_list);
+static LIST_HEAD(l3proto_list);
+static char *proto2str[IPPROTO_MAX] = {
+ [IPPROTO_TCP] = "tcp",
+ [IPPROTO_UDP] = "udp",
+ [IPPROTO_ICMP] = "icmp",
+ [IPPROTO_SCTP] = "sctp"
+};
+static char *l3proto2str[AF_MAX] = {
+ [AF_INET] = "ipv4",
+ [AF_INET6] = "ipv6"
+};
+static struct nfct_proto *findproto(char *name);
+static struct nfct_l3proto *findl3proto(char *name);
+
+/* handler used for nfnl_listen */
+static int callback_handler(struct sockaddr_nl *nladdr,
+ struct nlmsghdr *n, void *arg)
+{
+ struct nfct_handle *cth = (struct nfct_handle *) arg;
+ int ret;
+
+ if (NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK &&
+ NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK_EXP) {
+ nfnl_dump_packet(n, n->nlmsg_len, "callback_handler");
+ return 0;
+ }
+
+ if (!cth)
+ return -ENODEV;
+
+ if (!cth->handler)
+ return -ENODEV;
+
+ ret = cth->handler(cth, n, NULL);
+
+ return ret;
+}
+
+struct nfct_handle *nfct_open_nfnl(struct nfnl_handle *nfnlh,
+ u_int8_t subsys_id,
+ unsigned int subscriptions)
+{
+ struct nfct_handle *cth;
+
+ cth = (struct nfct_handle *) malloc(sizeof(struct nfct_handle));
+ if (!cth)
+ return NULL;
+
+ memset(cth, 0, sizeof(*cth));
+ cth->nfnlh = nfnlh;
+
+ if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK) {
+ cth->nfnlssh_ct = nfnl_subsys_open(cth->nfnlh,
+ NFNL_SUBSYS_CTNETLINK,
+ IPCTNL_MSG_MAX,
+ subscriptions);
+ if (!cth->nfnlssh_ct)
+ goto out_free;
+ }
+
+ if (subsys_id == 0 || subsys_id == NFNL_SUBSYS_CTNETLINK_EXP) {
+ cth->nfnlssh_exp = nfnl_subsys_open(cth->nfnlh,
+ NFNL_SUBSYS_CTNETLINK_EXP,
+ IPCTNL_MSG_EXP_MAX,
+ subscriptions);
+ if (!cth->nfnlssh_exp)
+ goto out_free;
+ }
+
+ return cth;
+
+out_free:
+ if (cth->nfnlssh_exp) {
+ nfnl_subsys_close(cth->nfnlssh_exp);
+ cth->nfnlssh_exp = NULL;
+ }
+ if (cth->nfnlssh_ct) {
+ nfnl_subsys_close(cth->nfnlssh_ct);
+ cth->nfnlssh_ct = NULL;
+ }
+ free(cth);
+ return NULL;
+}
+
+struct nfct_handle *nfct_open(u_int8_t subsys_id, unsigned subscriptions)
+{
+ struct nfnl_handle *nfnlh = nfnl_open();
+ struct nfct_handle *nfcth;
+
+ if (!nfnlh)
+ return NULL;
+
+ nfcth = nfct_open_nfnl(nfnlh, subsys_id, subscriptions);
+ if (!nfcth)
+ nfnl_close(nfnlh);
+
+ return nfcth;
+}
+
+int nfct_close(struct nfct_handle *cth)
+{
+ int err;
+
+ if (cth->nfnlssh_exp) {
+ nfnl_subsys_close(cth->nfnlssh_exp);
+ cth->nfnlssh_exp = NULL;
+ }
+ if (cth->nfnlssh_ct) {
+ nfnl_subsys_close(cth->nfnlssh_ct);
+ cth->nfnlssh_ct = NULL;
+ }
+
+ /* required by the new API */
+ cth->cb = NULL;
+ free(cth->nfnl_cb.data);
+
+ cth->nfnl_cb.call = NULL;
+ cth->nfnl_cb.data = NULL;
+ cth->nfnl_cb.attr_count = 0;
+
+ err = nfnl_close(cth->nfnlh);
+ free(cth);
+
+ return err;
+}
+
+int nfct_fd(struct nfct_handle *cth)
+{
+ return nfnl_fd(cth->nfnlh);
+}
+
+const struct nfnl_handle *nfct_nfnlh(struct nfct_handle *cth)
+{
+ return cth->nfnlh;
+}
+
+void nfct_register_callback(struct nfct_handle *cth, nfct_callback callback,
+ void *data)
+{
+ cth->callback = callback;
+ cth->callback_data = data;
+}
+
+void nfct_unregister_callback(struct nfct_handle *cth)
+{
+ cth->callback = NULL;
+ cth->callback_data = NULL;
+}
+
+static void nfct_build_tuple_ip(struct nfnlhdr *req, int size,
+ struct nfct_tuple *t)
+{
+ struct nfattr *nest;
+ struct nfct_l3proto *h;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_IP);
+
+ h = findl3proto(l3proto2str[t->l3protonum]);
+ if (h && h->build_tuple_proto)
+ h->build_tuple_proto(req, size, t);
+
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+static void nfct_build_tuple_proto(struct nfnlhdr *req, int size,
+ struct nfct_tuple *t)
+{
+ struct nfct_proto *h;
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_PROTO);
+
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTO_NUM, &t->protonum,
+ sizeof(u_int8_t));
+
+ h = findproto(proto2str[t->protonum]);
+
+ if (h && h->build_tuple_proto)
+ h->build_tuple_proto(req, size, t);
+
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void nfct_build_tuple(struct nfnlhdr *req, int size,
+ struct nfct_tuple *t, int type)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, type);
+
+ nfct_build_tuple_ip(req, size, t);
+ nfct_build_tuple_proto(req, size, t);
+
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+static void nfct_build_protoinfo(struct nfnlhdr *req, int size,
+ struct nfct_conntrack *ct)
+{
+ struct nfattr *nest;
+ struct nfct_proto *h;
+
+ h = findproto(proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum]);
+ if (h && h->build_protoinfo) {
+ nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
+ h->build_protoinfo(req, size, ct);
+ nfnl_nest_end(&req->nlh, nest);
+ }
+}
+
+static void nfct_build_protonat(struct nfnlhdr *req, int size,
+ struct nfct_conntrack *ct)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_NAT_PROTO);
+
+ switch (ct->tuple[NFCT_DIR_ORIGINAL].protonum) {
+#if 0
+ case IPPROTO_TCP:
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_TCP_MIN,
+ &ct->nat.l4min.tcp.port, sizeof(u_int16_t));
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_TCP_MAX,
+ &ct->nat.l4max.tcp.port, sizeof(u_int16_t));
+ break;
+ case IPPROTO_UDP:
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_UDP_MIN,
+ &ct->nat.l4min.udp.port, sizeof(u_int16_t));
+ nfnl_addattr_l(&req->nlh, size, CTA_PROTONAT_UDP_MAX,
+ &ct->nat.l4max.udp.port, sizeof(u_int16_t));
+ break;
+#endif
+ }
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+static void nfct_build_nat(struct nfnlhdr *req, int size,
+ struct nfct_conntrack *ct)
+{
+ struct nfattr *nest;
+
+ nest = nfnl_nest(&req->nlh, size, CTA_NAT);
+
+ nfnl_addattr_l(&req->nlh, size, CTA_NAT_MINIP,
+ &ct->nat.min_ip, sizeof(u_int32_t));
+
+ if (ct->nat.min_ip != ct->nat.max_ip)
+ nfnl_addattr_l(&req->nlh, size, CTA_NAT_MAXIP,
+ &ct->nat.max_ip, sizeof(u_int32_t));
+
+ if (ct->nat.l4min.all != ct->nat.l4max.all)
+ nfct_build_protonat(req, size, ct);
+
+ nfnl_nest_end(&req->nlh, nest);
+}
+
+void nfct_dump_tuple(struct nfct_tuple *tp)
+{
+ struct in_addr src = { .s_addr = tp->src.v4 };
+ struct in_addr dst = { .s_addr = tp->dst.v4 };
+
+ fprintf(stdout, "tuple %p: %u %s:%hu -> ", tp, tp->protonum,
+ inet_ntoa(src),
+ ntohs(tp->l4src.all));
+
+ fprintf(stdout, "%s:%hu\n", inet_ntoa(dst), ntohs(tp->l4dst.all));
+}
+
+static struct nfct_proto *findproto(char *name)
+{
+ struct list_head *i;
+ struct nfct_proto *cur = NULL, *handler = NULL;
+
+ if (!name)
+ return handler;
+
+ lib_dir = getenv("LIBNETFILTER_CONNTRACK_DIR");
+ if (!lib_dir)
+ lib_dir = LIBNETFILTER_CONNTRACK_DIR;
+
+ list_for_each(i, &proto_list) {
+ cur = (struct nfct_proto *) i;
+ if (strcmp(cur->name, name) == 0) {
+ handler = cur;
+ break;
+ }
+ }
+
+ if (!handler) {
+ char path[sizeof("nfct_proto_.so") + strlen(VERSION)
+ + strlen(name) + strlen(lib_dir)];
+ sprintf(path, "%s/nfct_proto_%s-%s.so", lib_dir, name, VERSION);
+ if (dlopen(path, RTLD_NOW))
+ handler = findproto(name);
+ else
+ fprintf(stderr, "%s\n", dlerror());
+ }
+
+ return handler;
+}
+
+static struct nfct_l3proto *findl3proto(char *name)
+{
+ struct list_head *i;
+ struct nfct_l3proto *cur = NULL, *handler = NULL;
+
+ if (!name)
+ return handler;
+
+ lib_dir = getenv("LIBNETFILTER_CONNTRACK_DIR");
+ if (!lib_dir)
+ lib_dir = LIBNETFILTER_CONNTRACK_DIR;
+
+ list_for_each(i, &l3proto_list) {
+ cur = (struct nfct_l3proto *) i;
+ if (strcmp(cur->name, name) == 0) {
+ handler = cur;
+ break;
+ }
+ }
+
+ if (!handler) {
+ char path[sizeof("nfct_l3proto_.so") + strlen(VERSION)
+ + strlen(name) + strlen(lib_dir)];
+ sprintf(path, "%s/nfct_l3proto_%s-%s.so",lib_dir,name,VERSION);
+ if (dlopen(path, RTLD_NOW))
+ handler = findl3proto(name);
+ else
+ fprintf(stderr, "%s\n", dlerror());
+ }
+
+ return handler;
+}
+
+int nfct_sprintf_status_assured(char *buf, struct nfct_conntrack *ct)
+{
+ int size = 0;
+
+ if (ct->status & IPS_ASSURED)
+ size = sprintf(buf, "[ASSURED] ");
+
+ return size;
+}
+
+int nfct_sprintf_status_seen_reply(char *buf, struct nfct_conntrack *ct)
+{
+ int size = 0;
+
+ if (!(ct->status & IPS_SEEN_REPLY))
+ size = sprintf(buf, "[UNREPLIED] ");
+
+ return size;
+}
+
+static void parse_ip(struct nfattr *attr, struct nfct_tuple *tuple)
+{
+ struct nfattr *tb[CTA_IP_MAX];
+ struct nfct_l3proto *h;
+
+ nfnl_parse_nested(tb, CTA_IP_MAX, attr);
+ h = findl3proto(l3proto2str[tuple->l3protonum]);
+ if (h && h->parse_proto)
+ h->parse_proto(tb, tuple);
+}
+
+static void parse_proto(struct nfattr *attr, struct nfct_tuple *tuple)
+{
+ struct nfattr *tb[CTA_PROTO_MAX];
+ struct nfct_proto *h;
+
+ nfnl_parse_nested(tb, CTA_PROTO_MAX, attr);
+ if (tb[CTA_PROTO_NUM-1])
+ tuple->protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
+
+ h = findproto(proto2str[tuple->protonum]);
+ if (h && h->parse_proto)
+ h->parse_proto(tb, tuple);
+}
+
+static void parse_tuple(struct nfattr *attr, struct nfct_tuple *tuple)
+{
+ struct nfattr *tb[CTA_TUPLE_MAX];
+
+ nfnl_parse_nested(tb, CTA_TUPLE_MAX, attr);
+
+ if (tb[CTA_TUPLE_IP-1])
+ parse_ip(tb[CTA_TUPLE_IP-1], tuple);
+ if (tb[CTA_TUPLE_PROTO-1])
+ parse_proto(tb[CTA_TUPLE_PROTO-1], tuple);
+}
+
+static void parse_mask(struct nfattr *attr, struct nfct_tuple *tuple,
+ u_int8_t l3protonum, u_int16_t protonum)
+{
+ struct nfattr *cda[CTA_TUPLE_MAX];
+
+ nfnl_parse_nested(cda, CTA_TUPLE_MAX, attr);
+
+ if (cda[CTA_TUPLE_IP-1]) {
+ struct nfattr *tb[CTA_IP_MAX];
+ struct nfct_l3proto *h;
+
+ nfnl_parse_nested(tb, CTA_IP_MAX, cda[CTA_TUPLE_IP-1]);
+ h = findl3proto(l3proto2str[l3protonum]);
+ if (h && h->parse_proto)
+ h->parse_proto(tb, tuple);
+ }
+ if (cda[CTA_TUPLE_PROTO-1]) {
+ struct nfattr *tb[CTA_PROTO_MAX];
+ struct nfct_proto *h;
+
+ nfnl_parse_nested(tb, CTA_PROTO_MAX, cda[CTA_TUPLE_PROTO-1]);
+ if (tb[CTA_PROTO_NUM-1])
+ tuple->protonum =
+ *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
+
+ h = findproto(proto2str[protonum]);
+ if (h && h->parse_proto)
+ h->parse_proto(tb, tuple);
+ }
+}
+
+static void parse_protoinfo(struct nfattr *attr, struct nfct_conntrack *ct)
+{
+ struct nfattr *tb[CTA_PROTOINFO_MAX];
+ struct nfct_proto *h;
+
+ nfnl_parse_nested(tb,CTA_PROTOINFO_MAX, attr);
+
+ h = findproto(proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum]);
+ if (h && h->parse_protoinfo)
+ h->parse_protoinfo(tb, ct);
+}
+
+static void nfct_parse_counters(struct nfattr *attr,
+ struct nfct_conntrack *ct,
+ enum ctattr_type parent)
+{
+ struct nfattr *tb[CTA_COUNTERS_MAX];
+ int dir = (parent == CTA_COUNTERS_ORIG ? NFCT_DIR_REPLY
+ : NFCT_DIR_ORIGINAL);
+
+ nfnl_parse_nested(tb, CTA_COUNTERS_MAX, attr);
+ if (tb[CTA_COUNTERS_PACKETS-1])
+ ct->counters[dir].packets
+ = __be64_to_cpu(*(u_int64_t *)
+ NFA_DATA(tb[CTA_COUNTERS_PACKETS-1]));
+ if (tb[CTA_COUNTERS_BYTES-1])
+ ct->counters[dir].bytes
+ = __be64_to_cpu(*(u_int64_t *)
+ NFA_DATA(tb[CTA_COUNTERS_BYTES-1]));
+ if (tb[CTA_COUNTERS32_PACKETS-1])
+ ct->counters[dir].packets
+ = ntohl(*(u_int32_t *)
+ NFA_DATA(tb[CTA_COUNTERS32_PACKETS-1]));
+ if (tb[CTA_COUNTERS32_BYTES-1])
+ ct->counters[dir].bytes
+ = ntohl(*(u_int32_t *)
+ NFA_DATA(tb[CTA_COUNTERS32_BYTES-1]));
+}
+
+static char *msgtype[] = {"[UNKNOWN]", "[NEW]", "[UPDATE]", "[DESTROY]"};
+
+static int typemsg2enum(u_int16_t type, u_int16_t flags)
+{
+ int ret = NFCT_MSG_UNKNOWN;
+
+ if (type == IPCTNL_MSG_CT_NEW) {
+ if (flags & (NLM_F_CREATE|NLM_F_EXCL))
+ ret = NFCT_MSG_NEW;
+ else
+ ret = NFCT_MSG_UPDATE;
+ } else if (type == IPCTNL_MSG_CT_DELETE)
+ ret = NFCT_MSG_DESTROY;
+
+ return ret;
+}
+
+static int nfct_conntrack_netlink_handler(struct nfct_handle *cth,
+ struct nlmsghdr *nlh, void *arg)
+{
+ struct nfct_conntrack ct;
+ unsigned int flags = 0;
+ struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
+ int type = NFNL_MSG_TYPE(nlh->nlmsg_type), ret = 0;
+ int len = nlh->nlmsg_len;
+ struct nfattr *cda[CTA_MAX];
+
+ len -= NLMSG_LENGTH(sizeof(struct nfgenmsg));
+ if (len < 0)
+ return -EINVAL;
+
+ memset(&ct, 0, sizeof(struct nfct_conntrack));
+
+ ct.tuple[NFCT_DIR_ORIGINAL].l3protonum = nfhdr->nfgen_family;
+ ct.tuple[NFCT_DIR_REPLY].l3protonum = nfhdr->nfgen_family;
+
+ nfnl_parse_attr(cda, CTA_MAX, NFA_DATA(nfhdr), len);
+
+ if (cda[CTA_TUPLE_ORIG-1])
+ parse_tuple(cda[CTA_TUPLE_ORIG-1],
+ &ct.tuple[NFCT_DIR_ORIGINAL]);
+
+ if (cda[CTA_TUPLE_REPLY-1])
+ parse_tuple(cda[CTA_TUPLE_REPLY-1],
+ &ct.tuple[NFCT_DIR_REPLY]);
+
+ if (cda[CTA_STATUS-1]) {
+ ct.status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1]));
+ flags |= NFCT_STATUS;
+ }
+
+ if (cda[CTA_PROTOINFO-1]) {
+ parse_protoinfo(cda[CTA_PROTOINFO-1], &ct);
+ flags |= NFCT_PROTOINFO;
+ }
+
+ if (cda[CTA_TIMEOUT-1]) {
+ ct.timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1]));
+ flags |= NFCT_TIMEOUT;
+ }
+
+ if (cda[CTA_MARK-1]) {
+ ct.mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1]));
+ flags |= NFCT_MARK;
+ }
+
+ if (cda[CTA_COUNTERS_ORIG-1]) {
+ nfct_parse_counters(cda[CTA_COUNTERS_ORIG-1], &ct,
+ NFA_TYPE(cda[CTA_COUNTERS_ORIG-1])-1);
+ flags |= NFCT_COUNTERS_ORIG;
+ }
+
+ if (cda[CTA_COUNTERS_REPLY-1]) {
+ nfct_parse_counters(cda[CTA_COUNTERS_REPLY-1], &ct,
+ NFA_TYPE(cda[CTA_COUNTERS_REPLY-1])-1);
+ flags |= NFCT_COUNTERS_RPLY;
+ }
+
+ if (cda[CTA_USE-1]) {
+ ct.use = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_USE-1]));
+ flags |= NFCT_USE;
+ }
+
+ if (cda[CTA_ID-1]) {
+ ct.id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_ID-1]));
+ flags |= NFCT_ID;
+ }
+
+ if (cth->callback)
+ ret = cth->callback((void *) &ct, flags,
+ typemsg2enum(type, nlh->nlmsg_flags),
+ cth->callback_data);
+
+ return ret;
+}
+
+int nfct_sprintf_protocol(char *buf, struct nfct_conntrack *ct)
+{
+ return (sprintf(buf, "%-8s %u ",
+ proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum] == NULL ?
+ "unknown" : proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum],
+ ct->tuple[NFCT_DIR_ORIGINAL].protonum));
+}
+
+int nfct_sprintf_timeout(char *buf, struct nfct_conntrack *ct)
+{
+ return sprintf(buf, "%u ", ct->timeout);
+}
+
+int nfct_sprintf_protoinfo(char *buf, struct nfct_conntrack *ct)
+{
+ int size = 0;
+ struct nfct_proto *h = NULL;
+
+ h = findproto(proto2str[ct->tuple[NFCT_DIR_ORIGINAL].protonum]);
+ if (h && h->print_protoinfo)
+ size += h->print_protoinfo(buf+size, &ct->protoinfo);
+
+ return size;
+}
+
+int nfct_sprintf_address(char *buf, struct nfct_tuple *t)
+{
+ int size = 0;
+ struct nfct_l3proto *h;
+
+ h = findl3proto(l3proto2str[t->l3protonum]);
+ if (h && h->print_proto)
+ size += h->print_proto(buf, t);
+
+ return size;
+}
+
+int nfct_sprintf_proto(char *buf, struct nfct_tuple *t)
+{
+ int size = 0;
+ struct nfct_proto *h = NULL;
+
+ h = findproto(proto2str[t->protonum]);
+ if (h && h->print_proto)
+ size += h->print_proto(buf, t);
+
+ return size;
+}
+
+int nfct_sprintf_counters(char *buf, struct nfct_conntrack *ct, int dir)
+{
+ return (sprintf(buf, "packets=%llu bytes=%llu ",
+ (unsigned long long) ct->counters[dir].packets,
+ (unsigned long long) ct->counters[dir].bytes));
+}
+
+int nfct_sprintf_mark(char *buf, struct nfct_conntrack *ct)
+{
+ return (sprintf(buf, "mark=%u ", ct->mark));
+}
+
+int nfct_sprintf_use(char *buf, struct nfct_conntrack *ct)
+{
+ return (sprintf(buf, "use=%u ", ct->use));
+}
+
+int nfct_sprintf_id(char *buf, u_int32_t id)
+{
+ return (sprintf(buf, "id=%u ", id));
+}
+
+int nfct_sprintf_conntrack(char *buf, struct nfct_conntrack *ct,
+ unsigned int flags)
+{
+ int size = 0;
+
+ size += nfct_sprintf_protocol(buf, ct);
+
+ if (flags & NFCT_TIMEOUT)
+ size += nfct_sprintf_timeout(buf+size, ct);
+
+ if (flags & NFCT_PROTOINFO)
+ size += nfct_sprintf_protoinfo(buf+size, ct);
+
+ size += nfct_sprintf_address(buf+size, &ct->tuple[NFCT_DIR_ORIGINAL]);
+ size += nfct_sprintf_proto(buf+size, &ct->tuple[NFCT_DIR_ORIGINAL]);
+
+ if (flags & NFCT_COUNTERS_ORIG)
+ size += nfct_sprintf_counters(buf+size, ct, NFCT_DIR_ORIGINAL);
+
+ if (flags & NFCT_STATUS)
+ size += nfct_sprintf_status_seen_reply(buf+size, ct);
+
+ size += nfct_sprintf_address(buf+size, &ct->tuple[NFCT_DIR_REPLY]);
+ size += nfct_sprintf_proto(buf+size, &ct->tuple[NFCT_DIR_REPLY]);
+
+ if (flags & NFCT_COUNTERS_RPLY)
+ size += nfct_sprintf_counters(buf+size, ct, NFCT_DIR_REPLY);
+
+ if (flags & NFCT_STATUS)
+ size += nfct_sprintf_status_assured(buf+size, ct);
+
+ if (flags & NFCT_MARK)
+ size += nfct_sprintf_mark(buf+size, ct);
+
+ if (flags & NFCT_USE)
+ size += nfct_sprintf_use(buf+size, ct);
+
+ /* Delete the last blank space */
+ size--;
+
+ return size;
+}
+
+int nfct_sprintf_conntrack_id(char *buf, struct nfct_conntrack *ct,
+ unsigned int flags)
+{
+ int size;
+
+ /* add a blank space, that's why the add 1 to the size */
+ size = nfct_sprintf_conntrack(buf, ct, flags) + 1;
+ if (flags & NFCT_ID)
+ size += nfct_sprintf_id(buf+size, ct->id);
+
+ /* Delete the last blank space */
+ return --size;
+}
+
+int nfct_default_conntrack_display(void *arg, unsigned int flags, int type,
+ void *data)
+{
+ char buf[512];
+ int size;
+ struct nfct_conntrack_compare *cmp = data;
+
+ if (cmp && !nfct_conntrack_compare(cmp->ct, arg, cmp))
+ return 0;
+
+ memset(buf, 0, sizeof(buf));
+ size = nfct_sprintf_conntrack(buf, arg, flags);
+ sprintf(buf+size, "\n");
+ fprintf(stdout, buf);
+
+ return 0;
+}
+
+int nfct_default_conntrack_display_id(void *arg, unsigned int flags, int type,
+ void *data)
+{
+ char buf[512];
+ int size;
+ struct nfct_conntrack_compare *cmp = data;
+
+ if (cmp && !nfct_conntrack_compare(cmp->ct, arg, cmp))
+ return 0;
+
+ memset(buf, 0, sizeof(buf));
+ size = nfct_sprintf_conntrack_id(buf, arg, flags);
+ sprintf(buf+size, "\n");
+ fprintf(stdout, buf);
+
+ return 0;
+}
+
+int nfct_default_conntrack_event_display(void *arg, unsigned int flags,
+ int type, void *data)
+{
+ char buf[512];
+ int size;
+ struct nfct_conntrack_compare *cmp = data;
+
+ if (cmp && !nfct_conntrack_compare(cmp->ct, arg, cmp))
+ return 0;
+
+ memset(buf, 0, sizeof(buf));
+ size = sprintf(buf, "%9s ", msgtype[type]);
+ size += nfct_sprintf_conntrack_id(buf + size, arg, flags);
+ sprintf(buf+size, "\n");
+ fprintf(stdout, buf);
+ fflush(stdout);
+
+ return 0;
+}
+
+int nfct_sprintf_expect_proto(char *buf, struct nfct_expect *exp)
+{
+ return(sprintf(buf, "%u proto=%d ", exp->timeout,
+ exp->tuple.protonum));
+}
+
+int nfct_sprintf_expect(char *buf, struct nfct_expect *exp)
+{
+ int size = 0;
+
+ size = nfct_sprintf_expect_proto(buf, exp);
+ size += nfct_sprintf_address(buf+size, &exp->tuple);
+ size += nfct_sprintf_proto(buf+size, &exp->tuple);
+
+ /* remove last blank space */
+ return --size;
+}
+
+int nfct_sprintf_expect_id(char *buf, struct nfct_expect *exp)
+{
+ int size = 0;
+
+ /* add a blank space, that's why the add 1 to the size */
+ size = nfct_sprintf_expect(buf, exp) + 1;
+ size += nfct_sprintf_id(buf+size, exp->id);
+
+ /* remove last blank space */
+ return --size;
+}
+
+int nfct_default_expect_display(void *arg, unsigned int flags, int type,
+ void *data)
+{
+ char buf[256];
+ int size = 0;
+
+ memset(buf, 0, sizeof(buf));
+ size = nfct_sprintf_expect(buf, arg);
+ sprintf(buf+size, "\n");
+ fprintf(stdout, buf);
+
+ return 0;
+}
+
+int nfct_default_expect_display_id(void *arg, unsigned int flags, int type,
+ void *data)
+{
+ char buf[256];
+ int size = 0;
+
+ size = nfct_sprintf_expect_id(buf, arg);
+ sprintf(buf+size, "\n");
+ fprintf(stdout, buf);
+
+ return 0;
+}
+
+static int nfct_expect_netlink_handler(struct nfct_handle *cth,
+ struct nlmsghdr *nlh, void *arg)
+{
+ struct nfgenmsg *nfhdr = NLMSG_DATA(nlh);
+ struct nfct_expect exp;
+ int type = NFNL_MSG_TYPE(nlh->nlmsg_type), ret = 0;
+ int len = nlh->nlmsg_len;
+ struct nfattr *cda[CTA_EXPECT_MAX];
+
+ len -= NLMSG_LENGTH(sizeof(struct nfgenmsg));
+ if (len < 0)
+ return -EINVAL;
+
+ memset(&exp, 0, sizeof(struct nfct_expect));
+
+ exp.tuple.l3protonum = nfhdr->nfgen_family;
+
+ nfnl_parse_attr(cda, CTA_EXPECT_MAX, NFA_DATA(nfhdr), len);
+
+ if (cda[CTA_EXPECT_TUPLE-1])
+ parse_tuple(cda[CTA_EXPECT_TUPLE-1], &exp.tuple);
+
+ if (cda[CTA_EXPECT_MASK-1])
+ parse_mask(cda[CTA_EXPECT_MASK-1], &exp.mask,
+ exp.tuple.l3protonum, exp.tuple.protonum);
+
+ if (cda[CTA_EXPECT_TIMEOUT-1])
+ exp.timeout = ntohl(*(u_int32_t *)
+ NFA_DATA(cda[CTA_EXPECT_TIMEOUT-1]));
+
+ if (cda[CTA_EXPECT_ID-1])
+ exp.id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]));
+
+ if (cth->callback)
+ ret = cth->callback((void *)&exp, 0,
+ typemsg2enum(type, nlh->nlmsg_flags),
+ cth->callback_data);
+
+ return 0;
+}
+
+struct nfct_conntrack *
+nfct_conntrack_alloc(struct nfct_tuple *orig, struct nfct_tuple *reply,
+ u_int32_t timeout, union nfct_protoinfo *proto,
+ u_int32_t status, u_int32_t mark,
+ u_int32_t id, struct nfct_nat *range)
+{
+ struct nfct_conntrack *ct;
+
+ ct = malloc(sizeof(struct nfct_conntrack));
+ if (!ct)
+ return NULL;
+ memset(ct, 0, sizeof(struct nfct_conntrack));
+
+ ct->tuple[NFCT_DIR_ORIGINAL] = *orig;
+ ct->tuple[NFCT_DIR_REPLY] = *reply;
+ ct->timeout = timeout;
+ ct->status = status;
+ ct->protoinfo = *proto;
+ ct->mark = mark;
+ if (id != NFCT_ANY_ID)
+ ct->id = id;
+ if (range)
+ ct->nat = *range;
+
+ return ct;
+}
+
+void nfct_conntrack_free(struct nfct_conntrack *ct)
+{
+ free(ct);
+}
+
+#define L3PROTONUM(ct) ct->tuple[NFCT_DIR_ORIGINAL].l3protonum
+#define L4PROTONUM(ct) ct->tuple[NFCT_DIR_ORIGINAL].protonum
+
+int nfct_conntrack_compare(struct nfct_conntrack *ct1,
+ struct nfct_conntrack *ct2,
+ struct nfct_conntrack_compare *cmp)
+{
+ struct nfct_l3proto *l3proto;
+ struct nfct_proto *proto;
+ unsigned int l3flags = cmp->l3flags;
+ unsigned int l4flags = cmp->l4flags;
+ unsigned int flags = cmp->flags;
+
+ if ((flags & NFCT_MARK) && (ct1->mark != ct2->mark))
+ return 0;
+
+ if (l3flags) {
+ if (ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum != AF_UNSPEC &&
+ ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum != AF_UNSPEC &&
+ ct1->tuple[NFCT_DIR_ORIGINAL].l3protonum !=
+ ct2->tuple[NFCT_DIR_ORIGINAL].l3protonum)
+ return 0;
+ if (ct1->tuple[NFCT_DIR_REPLY].l3protonum != AF_UNSPEC &&
+ ct2->tuple[NFCT_DIR_REPLY].l3protonum != AF_UNSPEC &&
+ ct1->tuple[NFCT_DIR_REPLY].l3protonum !=
+ ct2->tuple[NFCT_DIR_REPLY].l3protonum)
+ return 0;
+ l3proto = findl3proto(l3proto2str[L3PROTONUM(ct1)]);
+ if (l3proto && !l3proto->compare(ct1, ct2, l3flags))
+ return 0;
+ }
+
+ if (l4flags) {
+ if (ct1->tuple[NFCT_DIR_ORIGINAL].protonum != 0 &&
+ ct2->tuple[NFCT_DIR_ORIGINAL].protonum != 0 &&
+ ct1->tuple[NFCT_DIR_ORIGINAL].protonum !=
+ ct2->tuple[NFCT_DIR_ORIGINAL].protonum)
+ return 0;
+ if (ct1->tuple[NFCT_DIR_REPLY].protonum != 0 &&
+ ct2->tuple[NFCT_DIR_REPLY].protonum != 0 &&
+ ct1->tuple[NFCT_DIR_REPLY].protonum !=
+ ct2->tuple[NFCT_DIR_REPLY].protonum)
+ return 0;
+ proto = findproto(proto2str[L4PROTONUM(ct1)]);
+ if (proto && !proto->compare(ct1, ct2, l4flags))
+ return 0;
+ }
+
+ return 1;
+}
+
+int nfct_create_conntrack(struct nfct_handle *cth, struct nfct_conntrack *ct)
+{
+ struct nfnlhdr *req;
+ char buf[NFCT_BUFSIZE];
+ u_int32_t status = htonl(ct->status | IPS_CONFIRMED);
+ u_int32_t timeout = htonl(ct->timeout);
+ u_int32_t mark = htonl(ct->mark);
+ u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
+
+ req = (void *) buf;
+
+ memset(buf, 0, sizeof(buf));
+
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0, l3num, 0,
+ IPCTNL_MSG_CT_NEW,
+ NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|NLM_F_EXCL);
+
+ nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_ORIGINAL],
+ CTA_TUPLE_ORIG);
+ nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_REPLY],
+ CTA_TUPLE_REPLY);
+
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_STATUS, &status,
+ sizeof(u_int32_t));
+
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_TIMEOUT, &timeout,
+ sizeof(u_int32_t));
+
+ if (ct->mark != 0)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_MARK, &mark,
+ sizeof(u_int32_t));
+
+ nfct_build_protoinfo(req, sizeof(buf), ct);
+ if (ct->nat.min_ip != 0)
+ nfct_build_nat(req, sizeof(buf), ct);
+
+ return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
+}
+
+int nfct_update_conntrack(struct nfct_handle *cth, struct nfct_conntrack *ct)
+{
+ struct nfnlhdr *req;
+ char buf[NFCT_BUFSIZE];
+ u_int32_t status = htonl(ct->status | IPS_CONFIRMED);
+ u_int32_t timeout = htonl(ct->timeout);
+ u_int32_t id = htonl(ct->id);
+ u_int32_t mark = htonl(ct->mark);
+ u_int8_t l3num = ct->tuple[NFCT_DIR_ORIGINAL].l3protonum;
+
+ req = (void *) &buf;
+ memset(&buf, 0, sizeof(buf));
+
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0, l3num, 0,
+ IPCTNL_MSG_CT_NEW, NLM_F_REQUEST|NLM_F_ACK);
+
+ nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_ORIGINAL],
+ CTA_TUPLE_ORIG);
+ nfct_build_tuple(req, sizeof(buf), &ct->tuple[NFCT_DIR_REPLY],
+ CTA_TUPLE_REPLY);
+
+ if (ct->status != 0)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_STATUS, &status,
+ sizeof(u_int32_t));
+
+ if (ct->timeout != 0)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_TIMEOUT, &timeout,
+ sizeof(u_int32_t));
+
+ if (ct->mark != 0)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_MARK, &mark,
+ sizeof(u_int32_t));
+
+ if (ct->id != NFCT_ANY_ID)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ID, &id,
+ sizeof(u_int32_t));
+
+ nfct_build_protoinfo(req, sizeof(buf), ct);
+
+ return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
+}
+
+int nfct_delete_conntrack(struct nfct_handle *cth, struct nfct_tuple *tuple,
+ int dir, u_int32_t id)
+{
+ struct nfnlhdr *req;
+ char buf[NFCT_BUFSIZE];
+ int type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG;
+ u_int8_t l3num = tuple->l3protonum;
+
+ req = (void *) &buf;
+ memset(&buf, 0, sizeof(buf));
+
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0,
+ l3num, 0, IPCTNL_MSG_CT_DELETE,
+ NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
+
+ nfct_build_tuple(req, sizeof(buf), tuple, type);
+
+ if (id != NFCT_ANY_ID) {
+ id = htonl(id); /* to network byte order */
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ID, &id,
+ sizeof(u_int32_t));
+ }
+
+ return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
+}
+
+int nfct_get_conntrack(struct nfct_handle *cth, struct nfct_tuple *tuple,
+ int dir, u_int32_t id)
+{
+ int err;
+ struct nfnlhdr *req;
+ char buf[NFCT_BUFSIZE];
+ int type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG;
+ u_int8_t l3num = tuple->l3protonum;
+
+ cth->handler = nfct_conntrack_netlink_handler;
+
+ memset(&buf, 0, sizeof(buf));
+ req = (void *) &buf;
+
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req->nlh, 0,
+ l3num, 0, IPCTNL_MSG_CT_GET,
+ NLM_F_REQUEST|NLM_F_ACK);
+
+ nfct_build_tuple(req, sizeof(buf), tuple, type);
+
+ if (id != NFCT_ANY_ID) {
+ id = htonl(id); /* to network byte order */
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_ID, &id,
+ sizeof(u_int32_t));
+ }
+
+ err = nfnl_send(cth->nfnlh, &req->nlh);
+ if (err < 0)
+ return err;
+
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
+}
+
+static int __nfct_dump_conntrack_table(struct nfct_handle *cth, int zero,
+ int family)
+{
+ int err, msg;
+ struct nfnlhdr req;
+
+ memset(&req, 0, sizeof(req));
+ cth->handler = nfct_conntrack_netlink_handler;
+
+ if (zero)
+ msg = IPCTNL_MSG_CT_GET_CTRZERO;
+ else
+ msg = IPCTNL_MSG_CT_GET;
+
+ nfnl_fill_hdr(cth->nfnlssh_ct, &req.nlh, 0, family, 0,
+ msg, NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_DUMP);
+
+ err = nfnl_send(cth->nfnlh, &req.nlh);
+ if (err < 0)
+ return err;
+
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
+}
+
+int nfct_dump_conntrack_table(struct nfct_handle *cth, int family)
+{
+ return(__nfct_dump_conntrack_table(cth, 0, family));
+}
+
+int nfct_dump_conntrack_table_reset_counters(struct nfct_handle *cth,
+ int family)
+{
+ return(__nfct_dump_conntrack_table(cth, 1, family));
+}
+
+int nfct_event_conntrack(struct nfct_handle *cth)
+{
+ cth->handler = nfct_conntrack_netlink_handler;
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
+}
+
+void nfct_register_proto(struct nfct_proto *h)
+{
+ if (strcmp(h->version, VERSION) != 0) {
+ fprintf(stderr, "plugin `%s': version %s (I'm %s)\n",
+ h->name, h->version, VERSION);
+ exit(1);
+ }
+ list_add(&h->head, &proto_list);
+}
+
+void nfct_register_l3proto(struct nfct_l3proto *h)
+{
+ if (strcmp(h->version, VERSION) != 0) {
+ fprintf(stderr, "plugin `%s': version %s (I'm %s)\n",
+ h->name, h->version, VERSION);
+ exit(1);
+ }
+ list_add(&h->head, &l3proto_list);
+}
+
+int nfct_dump_expect_list(struct nfct_handle *cth, int family)
+{
+ int err;
+ struct nfnlhdr req;
+
+ memset(&req, 0, sizeof(req));
+
+ cth->handler = nfct_expect_netlink_handler;
+ nfnl_fill_hdr(cth->nfnlssh_exp, &req.nlh, 0, family, 0,
+ IPCTNL_MSG_EXP_GET, NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST);
+
+ err = nfnl_send(cth->nfnlh, &req.nlh);
+ if (err < 0)
+ return err;
+
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
+}
+
+int nfct_flush_conntrack_table(struct nfct_handle *cth, int family)
+{
+ struct nfnlhdr req;
+
+ memset(&req, 0, sizeof(req));
+
+ nfnl_fill_hdr(cth->nfnlssh_ct, (struct nlmsghdr *) &req,
+ 0, family, 0, IPCTNL_MSG_CT_DELETE,
+ NLM_F_REQUEST|NLM_F_ACK);
+
+ return nfnl_talk(cth->nfnlh, &req.nlh, 0, 0, NULL, NULL, NULL);
+}
+
+int nfct_get_expectation(struct nfct_handle *cth, struct nfct_tuple *tuple,
+ u_int32_t id)
+{
+ int err;
+ struct nfnlhdr *req;
+ char buf[NFCT_BUFSIZE];
+ u_int8_t l3num = tuple->l3protonum;
+
+ memset(&buf, 0, sizeof(buf));
+ req = (void *) &buf;
+
+ nfnl_fill_hdr(cth->nfnlssh_exp, &req->nlh, 0, l3num, 0,
+ IPCTNL_MSG_EXP_GET,
+ NLM_F_REQUEST|NLM_F_ACK);
+
+ cth->handler = nfct_expect_netlink_handler;
+ nfct_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER);
+
+ if (id != NFCT_ANY_ID)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_ID, &id,
+ sizeof(u_int32_t));
+
+ err = nfnl_send(cth->nfnlh, &req->nlh);
+ if (err < 0)
+ return err;
+
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
+}
+
+struct nfct_expect *
+nfct_expect_alloc(struct nfct_tuple *master, struct nfct_tuple *tuple,
+ struct nfct_tuple *mask, u_int32_t timeout,
+ u_int32_t id)
+{
+ struct nfct_expect *exp;
+
+ exp = malloc(sizeof(struct nfct_expect));
+ if (!exp)
+ return NULL;
+ memset(exp, 0, sizeof(struct nfct_expect));
+
+ exp->master = *master;
+ exp->tuple = *tuple;
+ exp->mask = *mask;
+ exp->timeout = timeout;
+ if (id != NFCT_ANY_ID)
+ exp->id = htonl(id);
+
+ return exp;
+}
+
+void nfct_expect_free(struct nfct_expect *exp)
+{
+ free(exp);
+}
+
+int nfct_create_expectation(struct nfct_handle *cth, struct nfct_expect *exp)
+{
+ struct nfnlhdr *req;
+ char buf[NFCT_BUFSIZE];
+ req = (void *) &buf;
+ u_int8_t l3num = exp->tuple.l3protonum;
+ u_int32_t timeout;
+ u_int16_t queuenr;
+
+ memset(&buf, 0, sizeof(buf));
+
+ nfnl_fill_hdr(cth->nfnlssh_exp, &req->nlh, 0, l3num, 0,
+ IPCTNL_MSG_EXP_NEW,
+ NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK);
+
+ nfct_build_tuple(req, sizeof(buf), &exp->master, CTA_EXPECT_MASTER);
+ nfct_build_tuple(req, sizeof(buf), &exp->tuple, CTA_EXPECT_TUPLE);
+ nfct_build_tuple(req, sizeof(buf), &exp->mask, CTA_EXPECT_MASK);
+
+ timeout = htonl(exp->timeout);
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_TIMEOUT,
+ &timeout, sizeof(u_int32_t));
+
+ queuenr = htons(exp->expectfn_queue_id);
+ if (queuenr)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_QUEUENR,
+ &queuenr, sizeof(u_int16_t));
+
+ return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
+}
+
+int nfct_delete_expectation(struct nfct_handle *cth, struct nfct_tuple *tuple,
+ u_int32_t id)
+{
+ struct nfnlhdr *req;
+ char buf[NFCT_BUFSIZE];
+ u_int8_t l3num = tuple->l3protonum;
+
+ memset(&buf, 0, sizeof(buf));
+ req = (void *) &buf;
+
+ nfnl_fill_hdr(cth->nfnlssh_exp, &req->nlh, 0, l3num,
+ 0, IPCTNL_MSG_EXP_DELETE,
+ NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK);
+
+ nfct_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER);
+
+ if (id != NFCT_ANY_ID)
+ nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_ID, &id,
+ sizeof(u_int32_t));
+
+ return nfnl_talk(cth->nfnlh, &req->nlh, 0, 0, NULL, NULL, NULL);
+}
+
+int nfct_event_expectation(struct nfct_handle *cth)
+{
+ cth->handler = nfct_expect_netlink_handler;
+ return nfnl_listen(cth->nfnlh, &callback_handler, cth);
+}
+
+int nfct_flush_expectation_table(struct nfct_handle *cth, int family)
+{
+ struct nfnlhdr req;
+
+ memset(&req, 0, sizeof(req));
+
+ nfnl_fill_hdr(cth->nfnlssh_exp, (struct nlmsghdr *) &req,
+ 0, family, 0, IPCTNL_MSG_EXP_DELETE,
+ NLM_F_REQUEST|NLM_F_ACK);
+
+ return nfnl_talk(cth->nfnlh, &req.nlh, 0, 0, NULL, NULL, NULL);
+}
More information about the netfilter-cvslog
mailing list