1#ifndef _LIBXT_SET_H 2#define _LIBXT_SET_H 3 4#include <unistd.h> 5#include <fcntl.h> 6#include <sys/types.h> 7#include <sys/socket.h> 8#include <errno.h> 9 10#ifdef DEBUG 11#define DEBUGP(x, args...) fprintf(stderr, x , ## args) 12#else 13#define DEBUGP(x, args...) 14#endif 15 16static int 17get_version(unsigned *version) 18{ 19 int res, sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); 20 struct ip_set_req_version req_version; 21 socklen_t size = sizeof(req_version); 22 23 if (sockfd < 0) 24 xtables_error(OTHER_PROBLEM, 25 "Can't open socket to ipset.\n"); 26 27 if (fcntl(sockfd, F_SETFD, FD_CLOEXEC) == -1) { 28 xtables_error(OTHER_PROBLEM, 29 "Could not set close on exec: %s\n", 30 strerror(errno)); 31 } 32 33 req_version.op = IP_SET_OP_VERSION; 34 res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req_version, &size); 35 if (res != 0) 36 xtables_error(OTHER_PROBLEM, 37 "Kernel module xt_set is not loaded in.\n"); 38 39 *version = req_version.version; 40 41 return sockfd; 42} 43 44static void 45get_set_byid(char *setname, ip_set_id_t idx) 46{ 47 struct ip_set_req_get_set req; 48 socklen_t size = sizeof(struct ip_set_req_get_set); 49 int res, sockfd; 50 51 sockfd = get_version(&req.version); 52 req.op = IP_SET_OP_GET_BYINDEX; 53 req.set.index = idx; 54 res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size); 55 close(sockfd); 56 57 if (res != 0) 58 xtables_error(OTHER_PROBLEM, 59 "Problem when communicating with ipset, errno=%d.\n", 60 errno); 61 if (size != sizeof(struct ip_set_req_get_set)) 62 xtables_error(OTHER_PROBLEM, 63 "Incorrect return size from kernel during ipset lookup, " 64 "(want %zu, got %zu)\n", 65 sizeof(struct ip_set_req_get_set), (size_t)size); 66 if (req.set.name[0] == '\0') 67 xtables_error(PARAMETER_PROBLEM, 68 "Set with index %i in kernel doesn't exist.\n", idx); 69 70 strncpy(setname, req.set.name, IPSET_MAXNAMELEN); 71} 72 73static void 74get_set_byname(const char *setname, struct xt_set_info *info) 75{ 76 struct ip_set_req_get_set req; 77 socklen_t size = sizeof(struct ip_set_req_get_set); 78 int res, sockfd; 79 80 sockfd = get_version(&req.version); 81 req.op = IP_SET_OP_GET_BYNAME; 82 strncpy(req.set.name, setname, IPSET_MAXNAMELEN); 83 req.set.name[IPSET_MAXNAMELEN - 1] = '\0'; 84 res = getsockopt(sockfd, SOL_IP, SO_IP_SET, &req, &size); 85 close(sockfd); 86 87 if (res != 0) 88 xtables_error(OTHER_PROBLEM, 89 "Problem when communicating with ipset, errno=%d.\n", 90 errno); 91 if (size != sizeof(struct ip_set_req_get_set)) 92 xtables_error(OTHER_PROBLEM, 93 "Incorrect return size from kernel during ipset lookup, " 94 "(want %zu, got %zu)\n", 95 sizeof(struct ip_set_req_get_set), (size_t)size); 96 if (req.set.index == IPSET_INVALID_ID) 97 xtables_error(PARAMETER_PROBLEM, 98 "Set %s doesn't exist.\n", setname); 99 100 info->index = req.set.index; 101} 102 103static void 104parse_dirs_v0(const char *opt_arg, struct xt_set_info_v0 *info) 105{ 106 char *saved = strdup(opt_arg); 107 char *ptr, *tmp = saved; 108 int i = 0; 109 110 while (i < (IPSET_DIM_MAX - 1) && tmp != NULL) { 111 ptr = strsep(&tmp, ","); 112 if (strncmp(ptr, "src", 3) == 0) 113 info->u.flags[i++] |= IPSET_SRC; 114 else if (strncmp(ptr, "dst", 3) == 0) 115 info->u.flags[i++] |= IPSET_DST; 116 else 117 xtables_error(PARAMETER_PROBLEM, 118 "You must spefify (the comma separated list of) 'src' or 'dst'."); 119 } 120 121 if (tmp) 122 xtables_error(PARAMETER_PROBLEM, 123 "Can't be more src/dst options than %i.", 124 IPSET_DIM_MAX); 125 126 free(saved); 127} 128 129static void 130parse_dirs(const char *opt_arg, struct xt_set_info *info) 131{ 132 char *saved = strdup(opt_arg); 133 char *ptr, *tmp = saved; 134 135 while (info->dim < IPSET_DIM_MAX && tmp != NULL) { 136 info->dim++; 137 ptr = strsep(&tmp, ","); 138 if (strncmp(ptr, "src", 3) == 0) 139 info->flags |= (1 << info->dim); 140 else if (strncmp(ptr, "dst", 3) != 0) 141 xtables_error(PARAMETER_PROBLEM, 142 "You must spefify (the comma separated list of) 'src' or 'dst'."); 143 } 144 145 if (tmp) 146 xtables_error(PARAMETER_PROBLEM, 147 "Can't be more src/dst options than %i.", 148 IPSET_DIM_MAX); 149 150 free(saved); 151} 152 153#endif /*_LIBXT_SET_H*/ 154