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 14 static void 15 parse_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 40 static 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 51 static 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 78 static 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