diff options
Diffstat (limited to 'extensions/libxt_set.h')
-rw-r--r-- | extensions/libxt_set.h | 52 |
1 files changed, 48 insertions, 4 deletions
diff --git a/extensions/libxt_set.h b/extensions/libxt_set.h index 47c3f5b6..5a1bdcf7 100644 --- a/extensions/libxt_set.h +++ b/extensions/libxt_set.h @@ -6,6 +6,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <errno.h> +#include "../iptables/xshared.h" #ifdef DEBUG #define DEBUGP(x, args...) fprintf(stderr, x , ## args) @@ -71,13 +72,13 @@ get_set_byid(char *setname, ip_set_id_t idx) } static void -get_set_byname(const char *setname, struct xt_set_info *info) +get_set_byname_only(const char *setname, struct xt_set_info *info, + int sockfd, unsigned int version) { - struct ip_set_req_get_set req; + struct ip_set_req_get_set req = { .version = version }; socklen_t size = sizeof(struct ip_set_req_get_set); - int res, sockfd; + int res; - sockfd = get_version(&req.version); req.op = IP_SET_OP_GET_BYNAME; strncpy(req.set.name, setname, IPSET_MAXNAMELEN); req.set.name[IPSET_MAXNAMELEN - 1] = '\0'; @@ -101,6 +102,49 @@ get_set_byname(const char *setname, struct xt_set_info *info) } static void +get_set_byname(const char *setname, struct xt_set_info *info) +{ + struct ip_set_req_get_set_family req; + socklen_t size = sizeof(struct ip_set_req_get_set_family); + int res, sockfd, version; + + sockfd = get_version(&req.version); + version = req.version; + req.op = IP_SET_OP_GET_FNAME; + strncpy(req.set.name, setname, IPSET_MAXNAMELEN); + req.set.name[IPSET_MAXNAMELEN - 1] = '\0'; + res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size); + + if (res != 0 && errno == EBADMSG) + /* Backward compatibility */ + return get_set_byname_only(setname, info, sockfd, version); + + close(sockfd); + if (res != 0) + xtables_error(OTHER_PROBLEM, + "Problem when communicating with ipset, errno=%d.\n", + errno); + if (size != sizeof(struct ip_set_req_get_set_family)) + xtables_error(OTHER_PROBLEM, + "Incorrect return size from kernel during ipset lookup, " + "(want %zu, got %zu)\n", + sizeof(struct ip_set_req_get_set_family), + (size_t)size); + if (req.set.index == IPSET_INVALID_ID) + xtables_error(PARAMETER_PROBLEM, + "Set %s doesn't exist.\n", setname); + if (!(req.family == afinfo->family || + req.family == NFPROTO_UNSPEC)) + xtables_error(PARAMETER_PROBLEM, + "The protocol family of set %s is %s, " + "which is not applicable.\n", + setname, + req.family == NFPROTO_IPV4 ? "IPv4" : "IPv6"); + + info->index = req.set.index; +} + +static void parse_dirs_v0(const char *opt_arg, struct xt_set_info_v0 *info) { char *saved = strdup(opt_arg); |