From f9dc4d2ed9f724057ed107839aa8ca6122f7b46c Mon Sep 17 00:00:00 2001 From: "/C=DE/ST=Berlin/L=Berlin/O=Netfilter Project/OU=Development/CN=pablo/emailAddress=pablo@netfilter.org" Date: Sun, 16 Oct 2005 19:44:46 +0000 Subject: Major changes, this library isn't libnfnetlink_conntrack anymore. We provide an high level interface that abstracts from the netlink sockets. Now users don't need to know anything about them. --- src/libnfnetlink_conntrack.c | 579 ------------------------------------------- 1 file changed, 579 deletions(-) delete mode 100644 src/libnfnetlink_conntrack.c (limited to 'src/libnfnetlink_conntrack.c') diff --git a/src/libnfnetlink_conntrack.c b/src/libnfnetlink_conntrack.c deleted file mode 100644 index 098505f..0000000 --- a/src/libnfnetlink_conntrack.c +++ /dev/null @@ -1,579 +0,0 @@ -/* libctnetlink.c: generic library for access to connection tracking. - * - * (C) 2001 by Jay Schulist - * (C) 2002-2005 by Harald Welte - * (C) 2005 by Pablo Neira Ayuso - * - * Development of this code funded by Astaro AG (http://www.astaro.com) - * - * this software may be used and distributed according to the terms - * of the gnu general public license, incorporated herein by reference. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define ctnl_error(format, args...) fprintf(stderr, format, ## args) - -struct nfnlhdr { - struct nlmsghdr nlh; - struct nfgenmsg nfmsg; -}; - -/*********************************************************************** - * low level stuff - ***********************************************************************/ -int ctnl_send(struct ctnl_handle *cth, struct nlmsghdr *n) -{ - return nfnl_send(&cth->nfnlh, n); -} - -int ctnl_wilddump_request(struct ctnl_handle *cth, int family, int type) -{ - struct nfnlhdr req; - - nfnl_fill_hdr(&cth->nfnlh, &req.nlh, 0, AF_INET, 0, - type, NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST); - - return nfnl_send(&cth->nfnlh, &req.nlh); -} - -/* handler used for nfnl_listen */ -static int callback_handler(struct sockaddr_nl *nladdr, - struct nlmsghdr *n, void *arg) -{ - struct ctnl_handle *cth = (struct ctnl_handle *) arg; - int type = NFNL_MSG_TYPE(n->nlmsg_type); - struct ctnl_msg_handler *hdlr = cth->handler[type]; - int ret; - - if (NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK && - NFNL_SUBSYS_ID(n->nlmsg_type) != NFNL_SUBSYS_CTNETLINK_EXP) { - ctnl_error("received message for wrong subsys, skipping\n"); - nfnl_dump_packet(n, n->nlmsg_len, "callback_handler"); - return 0; - } - - if (!hdlr) { - ctnl_error("no handler for type %d\n", type); - return 0; - } - - if (!hdlr->handler) { - ctnl_error("no handler function for type %d\n", type); - return 0; - } - - ret = hdlr->handler(nladdr, n, arg); - - return ret; -} - -/*********************************************************************** - * high level stuff - ***********************************************************************/ - -/** - * ctnl_open - open a libctnetlink handle - * - * cth: pointer to already allocated library handle - * subsys_id: ID of the subsystem - * subscriptions: netlink groups we are interested in - */ -int ctnl_open(struct ctnl_handle *cth, u_int8_t subsys_id, - unsigned subscriptions) -{ - int err; - u_int8_t cb_count; - - switch(subsys_id) { - case NFNL_SUBSYS_CTNETLINK: - cb_count = IPCTNL_MSG_MAX; - break; - case NFNL_SUBSYS_CTNETLINK_EXP: - cb_count = IPCTNL_MSG_EXP_MAX; - break; - default: - return -ENOENT; - break; - } - memset(cth, 0, sizeof(*cth)); - - err = nfnl_open(&cth->nfnlh, subsys_id, cb_count, subscriptions); - if (err < 0) { - return err; - } - - return 0; -} - -/** - * ctnl_close - close a libctnetlink handle - * - * cth: libctnetlink handle - */ -int ctnl_close(struct ctnl_handle *cth) -{ - int err; - - err = nfnl_close(&cth->nfnlh); - - return err; -} - -/* ctnl_register_handler - register handler for ctnetlink mesage type - * - * cth: libctnetlink handle - * hndlr: handler structure - */ -int ctnl_register_handler(struct ctnl_handle *cth, - struct ctnl_msg_handler *hndlr) -{ - if (hndlr->type >= IPCTNL_MSG_MAX) - return -EINVAL; - - cth->handler[hndlr->type] = hndlr; - - return 0; -} - -/** - * ctnl_unregister_handler - unregister handler for ctnetlink msgtype - * - * cth: libctnetlink handle - * type: message type - */ -int ctnl_unregister_handler(struct ctnl_handle *cth, int type) -{ - if (type >= IPCTNL_MSG_MAX) - return -EINVAL; - - cth->handler[type] = NULL; - return 0; -} - -int ctnl_flush_conntrack(struct ctnl_handle *cth) -{ - struct nfnlhdr *req; - char buf[sizeof(*req)]; - - memset(&buf, 0, sizeof(buf)); - req = (void *) &buf; - - nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf, - 0, AF_INET, 0, IPCTNL_MSG_CT_DELETE, - NLM_F_REQUEST|NLM_F_ACK); - - if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0 ) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -/** - * ctnl_list_conntrack - list connection tracking table - * cth: libctnetlink handle - * family: AF_INET, ... - */ -int ctnl_list_conntrack(struct ctnl_handle *cth, int family) -{ - if (ctnl_wilddump_request(cth, family, IPCTNL_MSG_CT_GET) < 0) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -int ctnl_list_conntrack_zero_counters(struct ctnl_handle *cth, int family) -{ - if (ctnl_wilddump_request(cth, family, IPCTNL_MSG_CT_GET_CTRZERO) < 0) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -int ctnl_event_conntrack(struct ctnl_handle *cth, int family) -{ - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -static void ctnl_build_tuple_ip(struct nfnlhdr *req, int size, - struct ctnl_tuple *t) -{ - struct nfattr *nest; - - nest = nfnl_nest(&req->nlh, size, CTA_TUPLE_IP); - - 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)); - - nfnl_nest_end(&req->nlh, nest); -} - -static void ctnl_build_tuple_proto(struct nfnlhdr *req, int size, - struct ctnl_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_int16_t)); - - switch(t->protonum) { - case IPPROTO_TCP: - case IPPROTO_UDP: - 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)); - /* This is an ICMP echo */ - if (t->l4dst.icmp.type == 8) - nfnl_addattr_l(&req->nlh, size, CTA_PROTO_ICMP_ID, - &t->l4src.icmp.id, sizeof(u_int16_t)); - break; - } - nfnl_nest_end(&req->nlh, nest); -} - -static void ctnl_build_tuple(struct nfnlhdr *req, int size, - struct ctnl_tuple *t, int type) -{ - struct nfattr *nest; - - nest = nfnl_nest(&req->nlh, size, type); - - ctnl_build_tuple_ip(req, size, t); - ctnl_build_tuple_proto(req, size, t); - - nfnl_nest_end(&req->nlh, nest); -} - -static void ctnl_build_protoinfo(struct nfnlhdr *req, int size, - struct ctnl_conntrack *ct) -{ - struct nfattr *nest; - - nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO); - - switch (ct->tuple[CTNL_DIR_ORIGINAL].protonum) { - case IPPROTO_TCP: { - struct nfattr *nest_proto; - 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); - break; - } - default: - break; - } - - nfnl_nest_end(&req->nlh, nest); -} - -static void ctnl_build_protonat(struct nfnlhdr *req, int size, - struct ctnl_conntrack *ct) -{ - struct nfattr *nest; - - nest = nfnl_nest(&req->nlh, size, CTA_NAT_PROTO); - - switch (ct->tuple[CTNL_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 ctnl_build_nat(struct nfnlhdr *req, int size, - struct ctnl_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) - ctnl_build_protonat(req, size, ct); - - nfnl_nest_end(&req->nlh, nest); -} - -static void ctnl_build_conntrack(struct nfnlhdr *req, int size, - struct ctnl_conntrack *ct) -{ - ctnl_build_tuple(req, size, &ct->tuple[CTNL_DIR_ORIGINAL], - CTA_TUPLE_ORIG); - ctnl_build_tuple(req, size, &ct->tuple[CTNL_DIR_REPLY], - CTA_TUPLE_REPLY); - - nfnl_addattr_l(&req->nlh, size, CTA_STATUS, &ct->status, - sizeof(unsigned int)); - nfnl_addattr_l(&req->nlh, size, CTA_TIMEOUT, &ct->timeout, - sizeof(unsigned long)); - - ctnl_build_protoinfo(req, size, ct); - if (ct->nat.min_ip != 0) - ctnl_build_nat(req, size, ct); -} - -/** - * ctnl_get_conntrack - get a connection from conntrack hashtable - * cth: libctnetlink handle - * t: tuple of connection to get - * cb: a struct nfattr to put the connection in - */ -int ctnl_get_conntrack(struct ctnl_handle *cth, - struct ctnl_tuple *tuple, - int dir) -{ - struct nfnlhdr *req; - char buf[CTNL_BUFFSIZE]; - - memset(&buf, 0, sizeof(buf)); - req = (void *) &buf; - - nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf, - 0, AF_INET, 0, IPCTNL_MSG_CT_GET, - NLM_F_REQUEST|NLM_F_ACK); - - ctnl_build_tuple(req, sizeof(buf), tuple, dir); - - if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -/** - * ctnl_del_conntrack - delete a connection from conntrack hashtable - * cth: libctnetlink handle - * t: tuple of to-be-deleted connection - */ -int ctnl_del_conntrack(struct ctnl_handle *cth, - struct ctnl_tuple *tuple, - int dir) -{ - struct nfnlhdr *req; - char buf[CTNL_BUFFSIZE]; - int type = dir ? CTA_TUPLE_REPLY : CTA_TUPLE_ORIG; - - memset(&buf, 0, sizeof(buf)); - req = (void *) &buf; - - nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf, - 0, AF_INET, 0, IPCTNL_MSG_CT_DELETE, - NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK); - - ctnl_build_tuple(req, sizeof(buf), tuple, type); - - if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} -static int new_update_conntrack(struct ctnl_handle *cth, - struct ctnl_conntrack *ct, - u_int16_t msg_flags) -{ - struct nfnlhdr *req; - char buf[CTNL_BUFFSIZE]; - - memset(&buf, 0, sizeof(buf)); - req = (void *) &buf; - - nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf, - 0, AF_INET, 0, IPCTNL_MSG_CT_NEW, - NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK|msg_flags); - - ctnl_build_conntrack(req, sizeof(buf), ct); - - if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0 ) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -/** - * ctnl_new_conntrack - create a connection in the conntrack hashtable - * cth: libctnetlink handle - * t: tuple of to-be-created connection - */ -int ctnl_new_conntrack(struct ctnl_handle *cth, struct ctnl_conntrack *ct) -{ - return new_update_conntrack(cth, ct, NLM_F_EXCL); -} - -int ctnl_upd_conntrack(struct ctnl_handle *cth, struct ctnl_conntrack *ct) -{ - return new_update_conntrack(cth, ct, 0); -} - -/** - * ctnl_list_expect - retrieve a list of expectations from conntrack subsys - * cth: libctnetlink handle - * family: AF_INET, ... - */ -int ctnl_list_expect(struct ctnl_handle *cth, int family) -{ - if (ctnl_wilddump_request(cth, family, IPCTNL_MSG_EXP_GET) < 0) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); - -} - -int ctnl_event_expect(struct ctnl_handle *cth, int family) -{ - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -int ctnl_flush_expect(struct ctnl_handle *cth) -{ - struct nfnlhdr *req; - char buf[sizeof(*req)]; - - memset(&buf, 0, sizeof(buf)); - req = (void *) &buf; - - nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf, - 0, AF_INET, 0, IPCTNL_MSG_EXP_DELETE, - NLM_F_REQUEST|NLM_F_ACK); - - if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0 ) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -/** - * ctnl_new_expect - create a new expectation - * - * cth: libctnetlink handle - * master_tuple: tuple of the master original direction - * t: direction, original or reply. - * exp_tuple: tuple of to-be-created expectation - * mask: mask of to-be-created expectation - * timeout: timeout of new expectation - */ -int ctnl_new_expect(struct ctnl_handle *cth, - struct ctnl_tuple *master, - struct ctnl_tuple *tuple, - struct ctnl_tuple *mask, - unsigned long timeout) -{ - struct nfnlhdr *req; - char buf[CTNL_BUFFSIZE]; - - memset(&buf, 0, sizeof(buf)); - req = (void *) &buf; - - nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf, - 0, AF_INET, 0, IPCTNL_MSG_EXP_NEW, - NLM_F_REQUEST|NLM_F_CREATE|NLM_F_ACK); - - ctnl_build_tuple(req, sizeof(buf), master, CTA_EXPECT_MASTER); - ctnl_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_TUPLE); - ctnl_build_tuple(req, sizeof(buf), mask, CTA_EXPECT_MASK); - - if (nfnl_addattr_l(&req->nlh, sizeof(buf), CTA_EXPECT_TIMEOUT, &timeout, - sizeof(timeout)) < 0) - return -1; - - if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0 ) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -/** - * ctnl_del_expect - delete an expectation from conntrack subsystem - * - * cth: libctnetlink handle - * t: tuple of to-be-deleted expectation - */ -int ctnl_del_expect(struct ctnl_handle *cth, - struct ctnl_tuple *tuple) -{ - struct nfnlhdr *req; - char buf[CTNL_BUFFSIZE]; - - memset(&buf, 0, sizeof(buf)); - req = (void *) &buf; - - nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf, - 0, AF_INET, 0, IPCTNL_MSG_EXP_DELETE, - NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_ACK); - - ctnl_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER); - - if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -int ctnl_get_expect(struct ctnl_handle *cth, - struct ctnl_tuple *tuple) -{ - struct nfnlhdr *req; - char buf[CTNL_BUFFSIZE]; - - memset(&buf, 0, sizeof(buf)); - req = (void *) &buf; - - nfnl_fill_hdr(&cth->nfnlh, (struct nlmsghdr *) &buf, - 0, AF_INET, 0, IPCTNL_MSG_EXP_GET, - NLM_F_REQUEST|NLM_F_ACK); - - ctnl_build_tuple(req, sizeof(buf), tuple, CTA_EXPECT_MASTER); - - if (nfnl_send(&cth->nfnlh, (struct nlmsghdr *)&buf) < 0 ) - return -1; - - return nfnl_listen(&cth->nfnlh, &callback_handler, cth); -} - -- cgit v1.2.3