summaryrefslogtreecommitdiffstats
path: root/extensions/libipt_set.h
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2009-06-11 12:27:09 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2009-06-11 12:27:09 +0200
commit2d280014e281b520280b1a11662aea0da2ffc59c (patch)
tree327ecdfa09c25638e94e73f6e81689b44befb600 /extensions/libipt_set.h
parentecd48dd6ba534deea7fd4d0ce20c7b5c00f4128f (diff)
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.
Diffstat (limited to 'extensions/libipt_set.h')
-rw-r--r--extensions/libipt_set.h37
1 files changed, 26 insertions, 11 deletions
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 <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
@@ -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",