From 3db4417c2dcc897e596722638a4d02f6b98e992d Mon Sep 17 00:00:00 2001 From: Eric Leblond Date: Tue, 1 Dec 2009 23:49:16 +0100 Subject: [PATCH] nufw: switch all conntrack code to new API. --- configure.ac | 3 - src/nufw/authsrv.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 159 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index b21bff0..52b277d 100644 --- a/configure.ac +++ b/configure.ac @@ -266,9 +266,6 @@ fi if test "${have_conntrack}" = "yes"; then AC_DEFINE_UNQUOTED([HAVE_LIBCONNTRACK],[1],[libconntrack has been found]) AC_CHECK_LIB([netfilter_conntrack], [nfct_callback_register], have_new_conntrack_api="yes", have_new_conntrack_api="", [-ldl -lnfnetlink]) - if test "${have_conntrack_fixedtimeout}" = "yes"; then - AC_DEFINE_UNQUOTED([HAVE_LIBCONNTRACK_FIXEDTIMEOUT],[1],[libconntrack with fixed timeout extension has been choosen]) - fi if test "${have_new_conntrack_api}" = "yes"; then AC_DEFINE_UNQUOTED([HAVE_NEW_NFCT_API],[1],[libconntrack new API has been found]) fi diff --git a/src/nufw/authsrv.c b/src/nufw/authsrv.c index a30d6cf..8703ea3 100644 --- a/src/nufw/authsrv.c +++ b/src/nufw/authsrv.c @@ -120,7 +120,164 @@ int auth_process_answer(char *dgram, int dgram_size) } #ifdef HAVE_LIBCONNTRACK +#ifdef HAVE_NEW_NFCT_API +static int conn_update_cb(enum nf_conntrack_msg_type type, + struct nf_conntrack *ct, + void *data) +{ + uint32_t *status = (uint32_t *) data; + + *status = nfct_get_attr_u32(ct, ATTR_STATUS); + return NFCT_CB_CONTINUE; +} + +static int build_nfct_from_message(struct nf_conntrack *ct, struct nuv4_conntrack_message_t *packet_hdr) +{ + /* use setters to build entry */ + nfct_set_attr_u8(ct, ATTR_L4PROTO, packet_hdr->ip_protocol); + + if (is_ipv4(&packet_hdr->ip_src) && is_ipv4(&packet_hdr->ip_dst)) { + nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET); + nfct_set_attr_u32(ct, ATTR_IPV4_SRC, + packet_hdr->ip_src.s6_addr32[3]); + nfct_set_attr_u32(ct, ATTR_IPV4_DST, + packet_hdr->ip_dst.s6_addr32[3]); + } else { + nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET6); +#if 0 + memcpy(&orig->src.v6, &packet_hdr->ip_src, + sizeof(orig->src.v6)); + memcpy(&orig->dst.v6, &packet_hdr->ip_dst, + sizeof(orig->dst.v6)); +#endif + } + + switch (packet_hdr->ip_protocol) { + case IPPROTO_TCP: + case IPPROTO_UDP: + nfct_set_attr_u16(ct, ATTR_PORT_SRC, + packet_hdr->src_port); + nfct_set_attr_u16(ct, ATTR_PORT_DST, + packet_hdr->dest_port); + break; + default: + return 0; + } + nfct_setobjopt(ct, NFCT_SOPT_SETUP_REPLY); + return 1; +} + +/** + * Process NuAuth message of type #AUTH_CONN_DESTROY + */ + +int auth_process_conn_destroy(char *dgram, int dgram_size) +{ + struct nuv4_conntrack_message_t *packet_hdr; + struct nf_conntrack *ct; + + /* check packet size */ + if (dgram_size < (int) sizeof(struct nuv4_conntrack_message_t)) { + return -1; + } + + packet_hdr = (struct nuv4_conntrack_message_t *) dgram; + + if (ntohs(packet_hdr->msg_length) != sizeof(struct nuv4_conntrack_message_t)) { + return -1; + } + + ct = nfct_new(); + + if (build_nfct_from_message(ct, packet_hdr)) { + debug_log_printf(DEBUG_AREA_GW | DEBUG_AREA_PACKET, + DEBUG_LEVEL_VERBOSE_DEBUG, + "Deleting entry from conntrack after NuAuth request"); + (void) nfct_query(cth, NFCT_Q_DESTROY, ct); + } + + nfct_destroy(ct); + return ntohs(packet_hdr->msg_length); +} + +/** + * Process NuAuth message of type #AUTH_CONN_UPDATE + */ +int auth_process_conn_update(char *dgram, int dgram_size) +{ + struct nuv4_conntrack_message_t *packet_hdr; + uint32_t status; + + struct nf_conntrack *ct; + /* check packet size */ + if (dgram_size < (int) sizeof(struct nuv4_conntrack_message_t)) { + debug_log_printf(DEBUG_AREA_GW, DEBUG_LEVEL_DEBUG, + "NuAuth sent too small message"); + return -1; + } + packet_hdr = (struct nuv4_conntrack_message_t *) dgram; + + if (ntohs(packet_hdr->msg_length) != sizeof(struct nuv4_conntrack_message_t)) { + return -1; + } + + if (packet_hdr->timeout) { + ct = nfct_new(); + if (build_nfct_from_message(ct, packet_hdr)) { + int ret; + /* getting conn to be able to update status without + * breaking anything */ + nfct_callback_register(cth, NFCT_T_ALL, conn_update_cb, &status); + ret = nfct_query(cth, NFCT_Q_GET, ct); + if (ret != 0) { + log_area_printf(DEBUG_AREA_MAIN, + DEBUG_LEVEL_WARNING, + "Conntrack fetching was impossible: %s", + strerror(errno)); + nfct_callback_unregister(cth); + nfct_destroy(ct); + return ret; + } + debug_log_printf(DEBUG_AREA_GW, + DEBUG_LEVEL_VERBOSE_DEBUG, + "conn status is %d", + status); + + debug_log_printf(DEBUG_AREA_GW, + DEBUG_LEVEL_VERBOSE_DEBUG, + "Will set timeout to %d after NuAuth request (was %d)", + ntohl(packet_hdr->timeout), + nfct_get_attr_u32(ct, ATTR_TIMEOUT) + ); + nfct_set_attr_u32(ct, ATTR_TIMEOUT, + ntohl(packet_hdr->timeout)); + + status |= IPS_FIXED_TIMEOUT; + nfct_set_attr_u32(ct, ATTR_STATUS, status); + debug_log_printf(DEBUG_AREA_GW, + DEBUG_LEVEL_VERBOSE_DEBUG, + "setting conn status to %d", + status); + ret = nfct_query(cth, NFCT_Q_UPDATE, ct); + + if (ret != 0) { + log_area_printf(DEBUG_AREA_MAIN, + DEBUG_LEVEL_WARNING, + "Conntrack update was impossible: %s", + strerror(errno)); + nfct_callback_unregister(cth); + nfct_destroy(ct); + return ret; + } + nfct_callback_unregister(cth); + } + nfct_destroy(ct); + } + return ntohs(packet_hdr->msg_length); +} + +#else int build_nfct_tuple_from_message(struct nfct_tuple *orig, struct nuv4_conntrack_message_t *packet_hdr) @@ -255,6 +412,8 @@ int auth_process_conn_update(char *dgram, int dgram_size) } return ntohs(packet_hdr->msg_length); } + +#endif /* HAVE_NEW_NFCT_API */ #endif /* HAVE_LIBCONNTRACK */ /** -- 1.6.1