1#ifndef _LIBIPT_SET_H 2#define _LIBIPT_SET_H 3 4#include <sys/types.h> 5#include <sys/socket.h> 6#include <errno.h> 7 8#ifdef DEBUG 9#define DEBUGP(x, args...) fprintf(stderr, x, ## args) 10#else 11#define DEBUGP(x, args...) 12#endif 13 14static void 15parse_bindings(const char *optarg, struct ipt_set_info *info) 16{ 17 char *saved = strdup(optarg); 18 char *ptr, *tmp = saved; 19 int i = 0; 20 21 while (i < (IP_SET_MAX_BINDINGS - 1) && tmp != NULL) { 22 ptr = strsep(&tmp, ","); 23 if (strncmp(ptr, "src", 3) == 0) 24 info->flags[i++] |= IPSET_SRC; 25 else if (strncmp(ptr, "dst", 3) == 0) 26 info->flags[i++] |= IPSET_DST; 27 else 28 exit_error(PARAMETER_PROBLEM, 29 "You must spefify (the comma separated list of) 'src' or 'dst'."); 30 } 31 32 if (tmp) 33 exit_error(PARAMETER_PROBLEM, 34 "Can't follow bindings deeper than %i.", 35 IP_SET_MAX_BINDINGS - 1); 36 37 free(saved); 38} 39 40static int get_set_getsockopt(void *data, socklen_t * size) 41{ 42 int sockfd = -1; 43 sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); 44 if (sockfd < 0) 45 exit_error(OTHER_PROBLEM, 46 "Can't open socket to ipset.\n"); 47 /* Send! */ 48 return getsockopt(sockfd, SOL_IP, SO_IP_SET, data, size); 49} 50 51static void get_set_byname(const char *setname, struct ipt_set_info *info) 52{ 53 struct ip_set_req_get_set req; 54 socklen_t size = sizeof(struct ip_set_req_get_set); 55 int res; 56 57 req.op = IP_SET_OP_GET_BYNAME; 58 req.version = IP_SET_PROTOCOL_VERSION; 59 strncpy(req.set.name, setname, IP_SET_MAXNAMELEN); 60 req.set.name[IP_SET_MAXNAMELEN - 1] = '\0'; 61 res = get_set_getsockopt(&req, &size); 62 if (res != 0) 63 exit_error(OTHER_PROBLEM, 64 "Problem when communicating with ipset, errno=%d.\n", 65 errno); 66 if (size != sizeof(struct ip_set_req_get_set)) 67 exit_error(OTHER_PROBLEM, 68 "Incorrect return size from kernel during ipset lookup, " 69 "(want %ld, got %ld)\n", 70 sizeof(struct ip_set_req_get_set), size); 71 if (req.set.index == IP_SET_INVALID_ID) 72 exit_error(PARAMETER_PROBLEM, 73 "Set %s doesn't exist.\n", setname); 74 75 info->index = req.set.index; 76} 77 78static void get_set_byid(char * setname, ip_set_id_t index) 79{ 80 struct ip_set_req_get_set req; 81 socklen_t size = sizeof(struct ip_set_req_get_set); 82 int res; 83 84 req.op = IP_SET_OP_GET_BYINDEX; 85 req.version = IP_SET_PROTOCOL_VERSION; 86 req.set.index = index; 87 res = get_set_getsockopt(&req, &size); 88 if (res != 0) 89 exit_error(OTHER_PROBLEM, 90 "Problem when communicating with ipset, errno=%d.\n", 91 errno); 92 if (size != sizeof(struct ip_set_req_get_set)) 93 exit_error(OTHER_PROBLEM, 94 "Incorrect return size from kernel during ipset lookup, " 95 "(want %ld, got %ld)\n", 96 sizeof(struct ip_set_req_get_set), size); 97 if (req.set.name[0] == '\0') 98 exit_error(PARAMETER_PROBLEM, 99 "Set id %i in kernel doesn't exist.\n", index); 100 101 strncpy(setname, req.set.name, IP_SET_MAXNAMELEN); 102} 103 104#endif /*_LIBIPT_SET_H*/ 105