#include "config.h" #ifdef HAVE_IPSET #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "triton.h" #include "log.h" #include "libnetlink.h" #include "ipset.h" #include "memdebug.h" static int __ipset_cmd(const char *name, in_addr_t addr, int cmd, int flags) { struct rtnl_handle rth; struct req { struct nlmsghdr n; struct nfgenmsg nf; char buf[4096]; } req; struct rtattr *tail1, *tail2; uint8_t protocol = IPSET_PROTOCOL; if (rtnl_open_byproto(&rth, 0, NETLINK_NETFILTER)) { log_error("ipset: cannot open rtnetlink\n"); return -1; } memset(&req, 0, sizeof(req) - 4096); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nfgenmsg)); req.n.nlmsg_flags = flags; req.n.nlmsg_type = cmd | (NFNL_SUBSYS_IPSET << 8); req.nf.nfgen_family = AF_INET; req.nf.version = NFNETLINK_V0; req.nf.res_id = 0; addattr_l(&req.n, 4096, IPSET_ATTR_PROTOCOL, &protocol, 1); addattr_l(&req.n, 4096, IPSET_ATTR_SETNAME, name, strlen(name) + 1); tail1 = addattr_nest(&req.n, MAX_MSG, IPSET_ATTR_DATA | NLA_F_NESTED); tail2 = addattr_nest(&req.n, MAX_MSG, IPSET_ATTR_IP | NLA_F_NESTED); addattr32(&req.n, 4096, IPSET_ATTR_IPADDR_IPV4 | NLA_F_NET_BYTEORDER, addr); addattr_nest_end(&req.n, tail2); addattr_nest_end(&req.n, tail1); if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0) goto out_err; rtnl_close(&rth); return 0; out_err: rtnl_close(&rth); return -1; } int __export ipset_add(const char *name, in_addr_t addr) { return __ipset_cmd(name, addr, IPSET_CMD_ADD, NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL); } int __export ipset_del(const char *name, in_addr_t addr) { return __ipset_cmd(name, addr, IPSET_CMD_DEL, NLM_F_REQUEST | NLM_F_ACK); } int __export ipset_flush(const char *name) { struct rtnl_handle rth; struct req { struct nlmsghdr n; struct nfgenmsg nf; char buf[4096]; } req; uint8_t protocol = IPSET_PROTOCOL; if (rtnl_open_byproto(&rth, 0, NETLINK_NETFILTER)) { log_error("ipset: cannot open rtnetlink\n"); return -1; } memset(&req, 0, sizeof(req) - 4096); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nfgenmsg)); req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; req.n.nlmsg_type = IPSET_CMD_FLUSH | (NFNL_SUBSYS_IPSET << 8); req.nf.nfgen_family = AF_INET; req.nf.version = NFNETLINK_V0; req.nf.res_id = 0; addattr_l(&req.n, 4096, IPSET_ATTR_PROTOCOL, &protocol, 1); addattr_l(&req.n, 4096, IPSET_ATTR_SETNAME, name, strlen(name) + 1); if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL, 0) < 0) goto out_err; rtnl_close(&rth); return 0; out_err: rtnl_close(&rth); return -1; } #else #include #include "triton.h" int __export ipset_add(const char *name, in_addr_t addr) { return -1; } int __export ipset_del(const char *name, in_addr_t addr) { return -1; } int __export ipset_flush(const char *name) { return -1; } #endif