/* * (C) 2005-2011 by Pablo Neira Ayuso * * 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 "internal/internal.h" static int __parse_message(const struct nlmsghdr *nlh) { u_int16_t type = NFNL_MSG_TYPE(nlh->nlmsg_type); u_int16_t flags = nlh->nlmsg_flags; int ret = NFCT_T_UNKNOWN; switch(type) { case IPCTNL_MSG_CT_NEW: /* same value for IPCTNL_MSG_EXP_NEW. */ if (flags & (NLM_F_CREATE|NLM_F_EXCL)) ret = NFCT_T_NEW; else ret = NFCT_T_UPDATE; break; case IPCTNL_MSG_CT_DELETE: /* same value for IPCTNL_MSG_EXP_DELETE. */ ret = NFCT_T_DESTROY; break; } return ret; } int __callback(struct nlmsghdr *nlh, struct nfattr *nfa[], void *data) { int ret = NFNL_CB_STOP; unsigned int type; struct nf_conntrack *ct = NULL; struct nf_expect *exp = NULL; struct __data_container *container = data; u_int8_t subsys = NFNL_SUBSYS_ID(nlh->nlmsg_type); if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct nfgenmsg))) { errno = EINVAL; return NFNL_CB_FAILURE; } type = __parse_message(nlh); if (!(type & container->type)) return NFNL_CB_CONTINUE; switch(subsys) { case NFNL_SUBSYS_CTNETLINK: ct = nfct_new(); if (ct == NULL) return NFNL_CB_FAILURE; __parse_conntrack(nlh, nfa, ct); if (container->h->cb) { ret = container->h->cb(type, ct, container->data); } else if (container->h->cb2) { ret = container->h->cb2(nlh, type, ct, container->data); } break; case NFNL_SUBSYS_CTNETLINK_EXP: exp = nfexp_new(); if (exp == NULL) return NFNL_CB_FAILURE; __parse_expect(nlh, nfa, exp); if (container->h->expect_cb) { ret = container->h->expect_cb(type, exp, container->data); } else if (container->h->expect_cb2) { ret = container->h->expect_cb2(nlh, type, exp, container->data); } break; default: errno = ENOTSUP; ret = NFNL_CB_FAILURE; break; } if (ret == NFCT_CB_STOLEN) return NFNL_CB_CONTINUE; if (ct) nfct_destroy(ct); if (exp) nfexp_destroy(exp); return ret; }