From 8e0608d31d988333ff04f3faaa6e851c0ecdbc6e Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Thu, 22 Apr 2010 16:52:29 +0200 Subject: Fourth stage to ipset-5 Add new userspace files: include/, lib/ and plus new files in src/. --- src/Makefile.am | 21 ++++++++ src/errcode.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ui.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 330 insertions(+) create mode 100644 src/Makefile.am create mode 100644 src/errcode.c create mode 100644 src/ui.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..28b28fa --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,21 @@ +include $(top_srcdir)/Make_global.am + +sbin_PROGRAMS = ipset +ipset_SOURCES = ipset.c \ + errcode.c \ + ipset_bitmap_ip.c \ + ipset_bitmap_ipmac.c \ + ipset_bitmap_port.c \ + ipset_hash_ip.c \ + ipset_hash_ipport.c \ + ipset_hash_ipportip.c \ + ipset_hash_ipportnet.c \ + ipset_hash_net.c \ + ipset_list_set.c \ + ipset_tree_ip.c \ + ui.c +ipset_LDADD = ../lib/libipset.la +AM_LDFLAGS = -static + +#%.o: %.c +# ${AM_VERBOSE_CC} ${CC} ${AM_DEPFLAGS} ${AM_CFLAGS} ${CFLAGS} -o $@ -c $< diff --git a/src/errcode.c b/src/errcode.c new file mode 100644 index 0000000..34b87a3 --- /dev/null +++ b/src/errcode.c @@ -0,0 +1,158 @@ +/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include /* assert */ +#include /* errno */ +#include /* strerror */ + +#include /* ipset_data_get */ +#include /* ipset_err */ +#include /* struct ipset_type */ +#include /* STRNEQ */ +#include /* prototypes */ +#include /* bitmap specific errcodes */ +#include /* hash specific errcodes */ + +/* Core kernel error codes */ +static const struct ipset_errcode_table core_errcode_table[] = { + /* Generic error codes */ + { EEXIST, 0, + "The set with the given name does not exist" }, + { IPSET_ERR_PROTOCOL, 0, + "Kernel error received: ipset protocol error" }, + + /* CREATE specific error codes */ + { EEXIST, IPSET_CMD_CREATE, + "Set cannot be created: set with the same name already exists" }, + { IPSET_ERR_FIND_TYPE, 0, + "Kernel error received: set type does not supported" }, + { IPSET_ERR_MAX_SETS, 0, + "Kernel error received: maximal number of sets reached, cannot create more." }, + { IPSET_ERR_INVALID_NETMASK, 0, + "The value of the netmask parameter is invalid" }, + { IPSET_ERR_INVALID_FAMILY, 0, + "The protocol family not supported by the set type" }, + + /* DESTROY specific error codes */ + { IPSET_ERR_BUSY, IPSET_CMD_DESTROY, + "Set cannot be destroyed: it is in use by a kernel component" }, + + /* FLUSH specific error codes */ + + /* RENAME specific error codes */ + { IPSET_ERR_EXIST_SETNAME2, IPSET_CMD_RENAME, + "Set cannot be renamed: a set with the new name already exists" }, + + /* SWAP specific error codes */ + { IPSET_ERR_EXIST_SETNAME2, IPSET_CMD_SWAP, + "Sets cannot be swapped: the second set does not exist" }, + { IPSET_ERR_TYPE_MISMATCH, IPSET_CMD_SWAP, + "The sets cannot be swapped: they type does not match" }, + + /* LIST/SAVE specific error codes */ + + /* Generic (CADT) error codes */ + { IPSET_ERR_INVALID_CIDR, 0, + "The value of the CIDR parameter of the IP address is invalid" }, + { IPSET_ERR_TIMEOUT, 0, + "Timeout cannot be used: set was created without timeout support" }, + + /* ADD specific error codes */ + { IPSET_ERR_EXIST, IPSET_CMD_ADD, + "Element cannot be added to the set: it's already added" }, + + /* DEL specific error codes */ + { IPSET_ERR_EXIST, IPSET_CMD_DEL, + "Element cannot be deleted from the set: it's not added" }, + + /* TEST specific error codes */ + + /* HEADER specific error codes */ + + /* TYPE specific error codes */ + { EEXIST, IPSET_CMD_TYPE, + "Kernel error received: set type does not supported" }, + + /* PROTOCOL specific error codes */ + + { }, +}; + +/* Bitmap type-specific error codes */ +static const struct ipset_errcode_table bitmap_errcode_table[] = { + /* Generic (CADT) error codes */ + { IPSET_ERR_BITMAP_RANGE, 0, + "Element is out of the range of the set" }, + { IPSET_ERR_BITMAP_RANGE_SIZE, IPSET_CMD_CREATE, + "The range you specified exceeds the size limit of the set type" }, + { }, +}; + +/* Hash type-specific error codes */ +static const struct ipset_errcode_table hash_errcode_table[] = { + /* Generic (CADT) error codes */ + { IPSET_ERR_HASH_FULL, 0, + "Hash is full, cannot add more elements" }, + { IPSET_ERR_HASH_ELEM, 0, + "Null-valued element, cannot be stored in a hash type of set" }, + { }, +}; + +#define MATCH_TYPENAME(a, b) STRNEQ(a, b, strlen(b)) + +/** + * ipset_errcode - interpret an error code + * @session: session structure + * @errcode: errcode + * + * Find the error code and print the appropriate + * error message. + * + * Returns -1. + */ +int +ipset_errcode(struct ipset_session *session, enum ipset_cmd cmd, int errcode) +{ + const struct ipset_errcode_table *table = core_errcode_table; + int i, generic; + + if (errcode >= IPSET_ERR_TYPE_SPECIFIC) { + const struct ipset_type *type; + + type = ipset_session_data_get(session, IPSET_OPT_TYPE); + if (type) { + if (MATCH_TYPENAME(type->name, "bitmap:")) + table = bitmap_errcode_table; + if (MATCH_TYPENAME(type->name, "hash:")) + table = hash_errcode_table; + } + } + +retry: + for (i = 0, generic = -1; table[i].errcode; i++) { + if (table[i].errcode == errcode + && (table[i].cmd == cmd || table[i].cmd == 0)) { + if (table[i].cmd == 0) { + generic = i; + continue; + } + return ipset_err(session, table[i].message); + } + } + if (generic != -1) + return ipset_err(session, table[generic].message); + /* Fall back to the core table */ + if (table != core_errcode_table) { + table = core_errcode_table; + goto retry; + } + if (errcode < IPSET_ERR_PRIVATE) + return ipset_err(session, "Kernel error received: %s", + strerror(errcode)); + else + return ipset_err(session, + "Undecoded error %u received from kernel", errcode); +} diff --git a/src/ui.c b/src/ui.c new file mode 100644 index 0000000..bc01e61 --- /dev/null +++ b/src/ui.c @@ -0,0 +1,151 @@ +/* Copyright 2007-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include /* IPSET_CMD_* */ +#include /* IPSET_*_ARG */ +#include /* ipset_envopt_parse */ +#include /* ipset_parse_family */ +#include /* ipset_print_family */ +#include /* prototypes */ + +/* Commands and environment options */ + +const struct ipset_commands ipset_commands[] = { + [IPSET_CMD_CREATE - 1] = { + .name = { "create", "c", "-N", "--create", NULL }, + .has_arg = IPSET_MANDATORY_ARG2, + .help = "SETNAME TYPENAME [type-specific-options]\n" + " Create a new set", + }, + [IPSET_CMD_DESTROY - 1] = { + .name = { "destroy", "x", "-X", "--destroy", NULL }, + .has_arg = IPSET_OPTIONAL_ARG, + .help = "[SETNAME]\n" + " Destroy a named set or all sets", + }, + [IPSET_CMD_FLUSH - 1] = { + .name = { "flush", "f", "-F", "--flush", NULL }, + .has_arg = IPSET_OPTIONAL_ARG, + .help = "[SETNAME]\n" + " Flush a named set or all sets", + }, + [IPSET_CMD_RENAME - 1] = { + .name = { "rename", "e", "-E", "--rename", NULL }, + .has_arg = IPSET_MANDATORY_ARG2, + .help = "FROM-SETNAME TO-SETNAME\n" + " Rename two sets", + }, + [IPSET_CMD_SWAP - 1] = { + .name = { "swap", "w", "-W", "--swap", NULL }, + .has_arg = IPSET_MANDATORY_ARG2, + .help = "FROM-SETNAME TO-SETNAME\n" + " Swap the contect of two existing sets", + }, + [IPSET_CMD_LIST - 1] = { + .name = { "list", "l", "-L", "--list", NULL }, + .has_arg = IPSET_OPTIONAL_ARG, + .help = "[SETNAME]\n" + " List the entries of a named set or all sets", + }, + [IPSET_CMD_SAVE - 1] = { + .name = { "save", "s", "-S", "--save", NULL }, + .has_arg = IPSET_OPTIONAL_ARG, + .help = "[SETNAME]\n" + " Save the named set or all sets to stdout", + }, + [IPSET_CMD_ADD - 1] = { + .name = { "add", "a", "-A", "--add", NULL }, + .has_arg = IPSET_MANDATORY_ARG2, + .help = "SETNAME ENTRY\n" + " Add entry to a named set", + }, + [IPSET_CMD_DEL - 1] = { + .name = { "del", "d", "-D", "--del", NULL }, + .has_arg = IPSET_MANDATORY_ARG2, + .help = "SETNAME ENTRY\n" + " Delete entry from a named set", + }, + [IPSET_CMD_TEST - 1] = { + .name = { "test", "t", "-T", "--test", NULL }, + .has_arg = IPSET_MANDATORY_ARG2, + .help = "SETNAME ENTRY\n" + " Test if entry exists in the named set", + }, + [IPSET_CMD_HELP - 1] = { + .name = { "help", "h", "-H", "-h", "--help", NULL }, + .has_arg = IPSET_OPTIONAL_ARG, + .help = "[TYPENAME]\n" + " Print help, and settype specific help", + }, + [IPSET_CMD_RESTORE - 1] = { + .name = { "restore", "r", "-R", "--restore", NULL }, + .has_arg = IPSET_NO_ARG, + .help = "\n" + " Restore a saved state", + }, + [IPSET_CMD_VERSION - 1] = { + .name = { "version", "v", "-V", "-v", "--version", NULL }, + .has_arg = IPSET_NO_ARG, + .help = "\n" + " Print version information", + }, + [IPSET_CMD_MAX - 1] = { }, +}; + +const struct ipset_envopts ipset_envopts[] = { + { .name = { "family", "--family", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .flag = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, .print = ipset_print_family, + .help = "inet|inet6\n" + " Specify family when creating a set\n" + " which supports multiple families.\n" + " The default family is INET.", + }, + { .name = { "-o", "--output", NULL }, + .has_arg = IPSET_MANDATORY_ARG, .flag = IPSET_OPT_MAX, + .parse = ipset_parse_output, + .help = "plain|save|xml\n" + " Specify output mode for listing sets.\n" + " Default value for \"list\" command is mode \"plain\"\n" + " and for \"save\" command is mode \"save\".", + }, + { .name = { "-s", "--sorted", NULL }, + .parse = ipset_envopt_parse, + .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_SORTED, + .help = "\n" + " Print elements sorted (if supported by the set type).", + }, + { .name = { "-q", "--quiet", NULL }, + .parse = ipset_envopt_parse, + .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_QUIET, + .help = "\n" + " Suppress any notice or warning message.", + }, + { .name = { "-r", "--resolve", NULL }, + .parse = ipset_envopt_parse, + .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_RESOLVE, + .help = "\n" + " Try to resolve IP addresses in the output (slow!)", + }, + { .name = { "-x", "--exist", NULL }, + .parse = ipset_envopt_parse, + .has_arg = IPSET_NO_ARG, .flag = IPSET_ENV_EXIST, + .help = "\n" + " Ignore errors when creating already created sets,\n" + " when adding already existing elements\n" + " or when deleting non-existing elements.", + }, + /* Aliases */ + { .name = { "-4", NULL }, + .has_arg = IPSET_NO_ARG, .flag = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + { .name = { "-6", NULL }, + .has_arg = IPSET_NO_ARG, .flag = IPSET_OPT_FAMILY, + .parse = ipset_parse_family, + }, + { }, +}; -- cgit v1.2.1