From 2d280014e281b520280b1a11662aea0da2ffc59c Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Thu, 11 Jun 2009 12:27:09 +0200 Subject: Updated set/SET match and target to support multiple ipset protocols. By checking the protocol version of the kernel part, the sockopt type of ipset protocols are all supported. Forward compatibility with the netlink based protocol is missing. The --set option of the set match is replaced by --match-set to avoid clashing with the recent match, but the old option is also kept. Manpages are updated, references to bindings removed. --- extensions/libipt_set.h | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'extensions/libipt_set.h') diff --git a/extensions/libipt_set.h b/extensions/libipt_set.h index f521e05f..0e9b0b54 100644 --- a/extensions/libipt_set.h +++ b/extensions/libipt_set.h @@ -1,6 +1,7 @@ #ifndef _LIBIPT_SET_H #define _LIBIPT_SET_H +#include #include #include #include @@ -37,28 +38,40 @@ parse_bindings(const char *opt_arg, struct ipt_set_info *info) free(saved); } -static int get_set_getsockopt(void *data, socklen_t * size) +static int get_version(unsigned *version) { - int sockfd = -1; - sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + int res, sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); + struct ip_set_req_version req_version; + socklen_t size = sizeof(req_version); + if (sockfd < 0) xtables_error(OTHER_PROBLEM, "Can't open socket to ipset.\n"); - /* Send! */ - return getsockopt(sockfd, SOL_IP, SO_IP_SET, data, size); + + req_version.op = IP_SET_OP_VERSION; + res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size); + if (res != 0) + xtables_error(OTHER_PROBLEM, + "Kernel module ip_set is not loaded in.\n"); + + *version = req_version.version; + + return sockfd; } static void get_set_byname(const char *setname, struct ipt_set_info *info) { struct ip_set_req_get_set req; socklen_t size = sizeof(struct ip_set_req_get_set); - int res; + int res, sockfd; + sockfd = get_version(&req.version); req.op = IP_SET_OP_GET_BYNAME; - req.version = IP_SET_PROTOCOL_VERSION; strncpy(req.set.name, setname, IP_SET_MAXNAMELEN); req.set.name[IP_SET_MAXNAMELEN - 1] = '\0'; - res = get_set_getsockopt(&req, &size); + res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size); + close(sockfd); + if (res != 0) xtables_error(OTHER_PROBLEM, "Problem when communicating with ipset, errno=%d.\n", @@ -79,12 +92,14 @@ static void get_set_byid(char * setname, ip_set_id_t idx) { struct ip_set_req_get_set req; socklen_t size = sizeof(struct ip_set_req_get_set); - int res; + int res, sockfd; + sockfd = get_version(&req.version); req.op = IP_SET_OP_GET_BYINDEX; - req.version = IP_SET_PROTOCOL_VERSION; req.set.index = idx; - res = get_set_getsockopt(&req, &size); + res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size); + close(sockfd); + if (res != 0) xtables_error(OTHER_PROBLEM, "Problem when communicating with ipset, errno=%d.\n", -- cgit v1.2.3