summaryrefslogtreecommitdiffstats
path: root/ipset.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipset.c')
-rw-r--r--ipset.c98
1 files changed, 66 insertions, 32 deletions
diff --git a/ipset.c b/ipset.c
index bd23758..d57318a 100644
--- a/ipset.c
+++ b/ipset.c
@@ -11,11 +11,8 @@
#include <string.h>
#include <errno.h>
#include <time.h>
-#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <arpa/inet.h>
@@ -23,7 +20,6 @@
#include <netdb.h>
#include <dlfcn.h>
#include <fcntl.h>
-/* #include <asm/bitops.h> */
#include "ipset.h"
@@ -75,9 +71,10 @@ static const char cmdflags[] = { ' ', /* CMD_NONE */
#define OPT_QUIET 0x0004U /* -q */
#define OPT_DEBUG 0x0008U /* -z */
#define OPT_BINDING 0x0010U /* -b */
-#define NUMBER_OF_OPT 5
+#define OPT_RESOLVE 0x0020U /* -r */
+#define NUMBER_OF_OPT 6
static const char optflags[] =
- { 'n', 's', 'q', 'z', 'b' };
+ { 'n', 's', 'q', 'z', 'b', 'r' };
static struct option opts_long[] = {
/* set operations */
@@ -105,6 +102,7 @@ static struct option opts_long[] = {
{"sorted", 0, 0, 's'},
{"quiet", 0, 0, 'q'},
{"binding", 1, 0, 'b'},
+ {"resolve", 0, 0, 'r'},
#ifdef IPSET_DEBUG
/* debug (if compiled with it) */
@@ -120,7 +118,7 @@ static struct option opts_long[] = {
};
static char opts_short[] =
- "-N:X::F::E:W:L::S::RA:D:T:B:U:nsqzb:Vh::H::";
+ "-N:X::F::E:W:L::S::RA:D:T:B:U:nrsqzb:Vh::H::";
/* Table of legal combinations of commands and options. If any of the
* given commands make an option legal, that option is legal.
@@ -132,21 +130,21 @@ static char opts_short[] =
static char commands_v_options[NUMBER_OF_CMD][NUMBER_OF_OPT] = {
/* -n -s -q -z -b */
- /*CREATE*/ {'x', 'x', ' ', ' ', 'x'},
- /*DESTROY*/ {'x', 'x', ' ', ' ', 'x'},
- /*FLUSH*/ {'x', 'x', ' ', ' ', 'x'},
- /*RENAME*/ {'x', 'x', ' ', ' ', 'x'},
- /*SWAP*/ {'x', 'x', ' ', ' ', 'x'},
- /*LIST*/ {' ', ' ', 'x', ' ', 'x'},
- /*SAVE*/ {'x', 'x', ' ', ' ', 'x'},
- /*RESTORE*/ {'x', 'x', ' ', ' ', 'x'},
- /*ADD*/ {'x', 'x', ' ', ' ', 'x'},
- /*DEL*/ {'x', 'x', ' ', ' ', 'x'},
- /*TEST*/ {'x', 'x', ' ', ' ', ' '},
- /*BIND*/ {'x', 'x', ' ', ' ', '+'},
- /*UNBIND*/ {'x', 'x', ' ', ' ', 'x'},
- /*HELP*/ {'x', 'x', 'x', ' ', 'x'},
- /*VERSION*/ {'x', 'x', 'x', ' ', 'x'},
+ /*CREATE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*DESTROY*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*FLUSH*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*RENAME*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*SWAP*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*LIST*/ {' ', ' ', 'x', ' ', 'x', ' '},
+ /*SAVE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*RESTORE*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*ADD*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*DEL*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*TEST*/ {'x', 'x', ' ', ' ', ' ', 'x'},
+ /*BIND*/ {'x', 'x', ' ', ' ', '+', 'x'},
+ /*UNBIND*/ {'x', 'x', ' ', ' ', 'x', 'x'},
+ /*HELP*/ {'x', 'x', 'x', ' ', 'x', 'x'},
+ /*VERSION*/ {'x', 'x', 'x', ' ', 'x', 'x'},
};
/* Main parser function */
@@ -349,11 +347,12 @@ static void kernel_error(unsigned cmd, int err)
{ ENOENT, 0, "Unknown set" },
{ EAGAIN, 0, "Sets are busy, try again later" },
{ ERANGE, CMD_CREATE, "No free slot remained to add a new set" },
- { ERANGE, 0, "IP/port is outside of the set" },
+ { ERANGE, 0, "IP/port/element is outside of the set or set is full" },
{ ENOEXEC, CMD_CREATE, "Invalid parameters to create a set" },
{ ENOEXEC, CMD_SWAP, "Sets with different types cannot be swapped" },
{ EEXIST, CMD_CREATE, "Set already exists" },
{ EEXIST, CMD_RENAME, "Set with new name already exists" },
+ { EEXIST, 0, "Set specified as element does not exist" },
{ EBUSY, 0, "Set is in use, operation not permitted" },
};
for (i = 0; i < sizeof(table)/sizeof(struct translate_error); i++) {
@@ -429,7 +428,7 @@ static void kernel_sendto(unsigned cmd, void *data, size_t size)
kernel_error(cmd, errno);
}
-static int kernel_getfrom_handleerrno(unsigned cmd, void *data, size_t * size)
+static int kernel_getfrom_handleerrno(unsigned cmd, void *data, socklen_t *size)
{
int res = wrapped_getsockopt(data, size);
@@ -856,7 +855,7 @@ void settype_register(struct settype *settype)
}
/* Find set functions */
-static struct set *set_find_byid(ip_set_id_t id)
+struct set *set_find_byid(ip_set_id_t id)
{
struct set *set = NULL;
ip_set_id_t i;
@@ -873,7 +872,7 @@ static struct set *set_find_byid(ip_set_id_t id)
return set;
}
-static struct set *set_find_byname(const char *name)
+struct set *set_find_byname(const char *name)
{
struct set *set = NULL;
ip_set_id_t i;
@@ -1134,6 +1133,11 @@ static size_t save_bindings(void *data, size_t offset, size_t len)
if (!(set && set_list[hash->binding]))
exit_error(OTHER_PROBLEM,
"Save binding failed, try again later.");
+ if (!set->settype->bindip_tostring)
+ exit_error(OTHER_PROBLEM,
+ "Internal error, binding is not supported with set %s"
+ " of settype %s\n",
+ set->name, set->settype->typename);
printf("-B %s %s -b %s\n",
set->name,
set->settype->bindip_tostring(set, hash->ip, OPT_NUMERIC),
@@ -1638,9 +1642,14 @@ static int set_bind(struct set *set, const char *adt,
DP("(%s, %s) -> %s", set ? set->name : IPSET_TOKEN_ALL, adt, binding);
/* Ugly */
- if (set && strcmp(set->settype->typename, "iptreemap") == 0)
+ if (set != NULL
+ && ((strcmp(set->settype->typename, "iptreemap") == 0)
+ || (strcmp(set->settype->typename, "ipportiphash") == 0)
+ || (strcmp(set->settype->typename, "ipportnethash") == 0)
+ || (strcmp(set->settype->typename, "setlist") == 0)))
exit_error(PARAMETER_PROBLEM,
- "iptreemap type of sets cannot be used at binding operations\n");
+ "%s type of sets cannot be used at binding operations\n",
+ set->settype->typename);
/* Alloc memory for the data to send */
size = sizeof(struct ip_set_req_bind);
if (op != IP_SET_OP_UNBIND_SET && adt[0] == ':')
@@ -1714,8 +1723,14 @@ static void set_restore_bind(struct set *set,
DP("%s -> %s", adt, binding);
if (strcmp(adt, IPSET_TOKEN_DEFAULT) == 0)
hash_restore->ip = 0;
- else
+ else {
+ if (!set->settype->bindip_parse)
+ exit_error(OTHER_PROBLEM,
+ "Internal error, binding is not supported with set %s"
+ " of settype %s\n",
+ set->name, set->settype->typename);
set->settype->bindip_parse(adt, &hash_restore->ip);
+ }
hash_restore->id = set->index;
hash_restore->binding = (set_find_byname(binding))->index;
DP("id %u, ip %u, binding %u",
@@ -1735,6 +1750,12 @@ static void print_bindings(struct set *set,
size_t offset = 0;
struct ip_set_hash_list *hash;
+ if (offset < size && !printip)
+ exit_error(OTHER_PROBLEM,
+ "Internal error, binding is not supported with set %s"
+ " of settype %s\n",
+ set->name, set->settype->typename);
+
while (offset < size) {
hash = (struct ip_set_hash_list *) (data + offset);
printf("%s -> %s\n",
@@ -1747,7 +1768,7 @@ static void print_bindings(struct set *set,
/* Help function to set_list() */
static size_t print_set(void *data, unsigned options)
{
- struct ip_set_list *setlist = (struct ip_set_list *) data;
+ struct ip_set_list *setlist = data;
struct set *set = set_list[setlist->index];
struct settype *settype = set->settype;
size_t offset;
@@ -1781,7 +1802,8 @@ static size_t print_set(void *data, unsigned options)
/* Print bindings */
printf("Bindings:\n");
offset += setlist->members_size;
- print_bindings(set,
+ if (set->settype->bindip_tostring)
+ print_bindings(set,
data + offset, setlist->bindings_size, options,
settype->bindip_tostring);
@@ -1798,6 +1820,10 @@ static int try_list_sets(const char name[IP_SET_MAXNAMELEN],
socklen_t size, req_size;
int res = 0;
+ /* Default is numeric listing */
+ if (!(options & (OPT_RESOLVE|OPT_NUMERIC)))
+ options |= OPT_NUMERIC;
+
DP("%s", name);
/* Load set_list from kernel */
size = req_size = load_set_list(name, &idx,
@@ -1907,7 +1933,8 @@ static void set_help(const struct settype *settype)
" Prints version information\n\n"
"Options:\n"
" --sorted -s Numeric sort of the IPs in -L\n"
- " --numeric -n Numeric output of addresses in a -L\n"
+ " --numeric -n Numeric output of addresses in a -L (default)\n"
+ " --resolve -r Try to resolve addresses in a -L\n"
" --quiet -q Suppress any output to stdout and stderr.\n"
" --binding -b Specifies the binding for -B\n");
printf(debughelp);
@@ -2143,6 +2170,11 @@ int parse_commandline(int argc, char *argv[])
add_option(&options, OPT_NUMERIC);
break;
+ case 'r':
+ if (!(options & OPT_NUMERIC))
+ add_option(&options, OPT_RESOLVE);
+ break;
+
case 's':
add_option(&options, OPT_SORTED);
break;
@@ -2269,6 +2301,8 @@ int parse_commandline(int argc, char *argv[])
break;
case CMD_BIND:
+ fprintf(stderr, "Warning: binding will be removed from the next release.\n"
+ "Please replace bindigs with sets of ipportmap and ipportiphash types\n");
if (restore)
set_restore_bind(set, adt, binding);
else