summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2010-10-24 21:42:48 +0200
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>2010-10-24 21:42:48 +0200
commit0d32c5c070f817229110f92d7b31df9a3e4eeec5 (patch)
tree5ee04a9e03de32d2029ad0d708811e382ca922d1 /src
parent62a3d29539aa109fed1c8a20d63ef95948b13842 (diff)
Fixes, cleanups, commentsv5.0-pre8
- More comments added to the code - ICMP and ICMPv6 support added to the hash:ip,port, hash:ip,port,ip and hash:ip,port,net types - hash:net and hash:ip,port,net types are reworked - hash:net,port type added - Wrong direction parameters fixed in hash:ip,port - Helps and manpage are updated - More tests added - Ugly macros are rewritten to functions in parse.c (Holger Eitzenberger) - resize related bug in hash types fixed (Holger Eitzenberger) - autoreconf patches by Jan Engelhardt applied - netlink patch minimalized: dumping can be initialized by a second parsing of the message (thanks to David and Patrick for the suggestion) - IPv4/IPv6 address attributes are introduced in order to fix the context (suggested by David)
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/errcode.c20
-rw-r--r--src/ipset.862
-rw-r--r--src/ipset.c47
-rw-r--r--src/ipset_bitmap_ip.c4
-rw-r--r--src/ipset_bitmap_ipmac.c5
-rw-r--r--src/ipset_bitmap_port.c11
-rw-r--r--src/ipset_hash_ip.c5
-rw-r--r--src/ipset_hash_ipport.c20
-rw-r--r--src/ipset_hash_ipportip.c20
-rw-r--r--src/ipset_hash_ipportnet.c21
-rw-r--r--src/ipset_hash_net.c5
-rw-r--r--src/ipset_hash_netport.c119
-rw-r--r--src/ipset_list_set.c3
-rw-r--r--src/ui.c34
16 files changed, 289 insertions, 89 deletions
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000..6166aba
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1 @@
+/ipset
diff --git a/src/Makefile.am b/src/Makefile.am
index ebd08a3..ce7de24 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -11,6 +11,7 @@ ipset_SOURCES = ipset.c \
ipset_hash_ipportip.c \
ipset_hash_ipportnet.c \
ipset_hash_net.c \
+ ipset_hash_netport.c \
ipset_list_set.c \
ui.c
ipset_LDADD = ../lib/libipset.la
diff --git a/src/errcode.c b/src/errcode.c
index ae0d8c8..313c500 100644
--- a/src/errcode.c
+++ b/src/errcode.c
@@ -32,7 +32,8 @@ static const struct ipset_errcode_table core_errcode_table[] = {
{ 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." },
+ "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,
@@ -63,6 +64,10 @@ static const struct ipset_errcode_table core_errcode_table[] = {
"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" },
+ { IPSET_ERR_IPADDR_IPV4, 0,
+ "An IPv4 address is expected, but not received" },
+ { IPSET_ERR_IPADDR_IPV6, 0,
+ "An IPv6 address is expected, but not received" },
/* ADD specific error codes */
{ IPSET_ERR_EXIST, IPSET_CMD_ADD,
@@ -119,23 +124,25 @@ static const struct ipset_errcode_table list_errcode_table[] = {
{ IPSET_ERR_BEFORE, 0,
"No reference set specified." },
{ IPSET_ERR_NAMEREF, 0,
- "The set to which you referred with 'before' or 'after' does not exist." },
+ "The set to which you referred with 'before' or 'after' "
+ "does not exist." },
{ IPSET_ERR_LIST_FULL, 0,
"The set is full, more elements cannot be added." },
{ IPSET_ERR_REF_EXIST, 0,
- "The set to which you referred with 'before' or 'after' is not added to the set." },
+ "The set to which you referred with 'before' or 'after' "
+ "is not added to the set." },
{ },
};
#define MATCH_TYPENAME(a, b) STRNEQ(a, b, strlen(b))
/**
- * ipset_errcode - interpret an error code
+ * ipset_errcode - interpret a kernel error code
* @session: session structure
* @errcode: errcode
*
* Find the error code and print the appropriate
- * error message.
+ * error message into the error buffer.
*
* Returns -1.
*/
@@ -182,5 +189,6 @@ retry:
strerror(errcode));
else
return ipset_err(session,
- "Undecoded error %u received from kernel", errcode);
+ "Undecoded error %u received from kernel",
+ errcode);
}
diff --git a/src/ipset.8 b/src/ipset.8
index c4f6a6b..2169c36 100644
--- a/src/ipset.8
+++ b/src/ipset.8
@@ -13,7 +13,7 @@
.\" You should have received a copy of the GNU General Public License
.\" along with this program; if not, write to the Free Software
.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-.TH "IPSET" "8" "Jun 11, 2010" "Jozsef Kadlecsik" ""
+.TH "IPSET" "8" "Oct 15, 2010" "Jozsef Kadlecsik" ""
.SH "NAME"
ipset \(em administration tool for IP sets
.SH "SYNOPSIS"
@@ -82,7 +82,7 @@ type specific options. If the
\fB\-exist\fR
option is specified,
\fBipset\fR
-ignores the error otherwise raised when the the same set (setname and create parameters
+ignores the error otherwise raised when the same set (setname and create parameters
are identical) already exists.
.TP
\fBadd\fP \fISETNAME\fP \fIADD\-ENTRY\fP [ \fIADD\-OPTIONS\fP ]
@@ -97,7 +97,7 @@ Delete an entry from a set. If the
\fB\-exist\fR
option is specified,
\fBipset\fR
-ignores if the entry does not added (expired) to the set.
+ignores if the entry does not added to (already expired from) the set.
.TP
\fBtest\fP \fISETNAME\fP \fITEST\-ENTRY\fP [ \fITEST\-OPTIONS\fP ]
Test wether an entry is in a set or not. Exit status number is zero
@@ -230,19 +230,19 @@ The \fBbitmap:ip\fR set type uses a memory range to store either IPv4 host
(default) or IPv4 network addresses. A \fBbitmap:ip\fR type of set can store up
to 65536 entries.
.PP
-\fICREATE\-OPTIONS\fR := \fBrange\fP \fIfrom\-ip\fP\-\fIto\-ip\fR|\fIip\fR/\fIcidr\fR [ \fBnetmask\fP \fIcidr\fP ] [ \fBtimeout\fR \fIvalue\fR ]
+\fICREATE\-OPTIONS\fR := \fBrange\fP \fIfromip\fP\-\fItoip\fR|\fIip\fR/\fIcidr\fR [ \fBnetmask\fP \fIcidr\fP ] [ \fBtimeout\fR \fIvalue\fR ]
.PP
-\fIADD\-ENTRY\fR := { \fIipaddr\fR | \fIfromaddr\fR\-\fItoaddr\fR | \fIipaddr\fR/\fIcidr\fR }
+\fIADD\-ENTRY\fR := { \fIipaddr\fR | \fIfromip\fR\-\fItoip\fR | \fIipaddr\fR/\fIcidr\fR }
.PP
\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ]
.PP
-\fIDEL\-ENTRY\fR := { \fIipaddr\fR | \fIfromaddr\fR\-\fItoaddr\fR | \fIipaddr\fR/\fIcidr\fR }
+\fIDEL\-ENTRY\fR := { \fIipaddr\fR | \fIfromip\fR\-\fItoip\fR | \fIipaddr\fR/\fIcidr\fR }
.PP
\fITEST\-ENTRY\fR := \fIipaddr\fR
.PP
Mandatory \fBcreate\fR options:
.TP
-\fBrange\fP \fIfrom\-ip\fP\-\fIto\-ip\fR|\fIip\fR/\fIcidr\fR
+\fBrange\fP \fIfromip\fP\-\fItoip\fR|\fIip\fR/\fIcidr\fR
Create the set from the specified inclusive address range expressed in an
IPv4 address range or network. The size of the range (in entries) cannot exceed
the limit of maximum 65536 elements.
@@ -251,10 +251,10 @@ Optional \fBcreate\fR options:
.TP
\fBnetmask\fP \fIcidr\fP
When the optional \fBnetmask\fP parameter specified, network addresses will be
-stored in the set instead of IP host addresses. The \fIcidr\fR value must be
+stored in the set instead of IP host addresses. The \fIcidr\fR prefix value must be
between 1\-32.
An IP address will be in the set if the network address, which is resulted by
-masking the address with the specified netmask calculated from the cidr value,
+masking the address with the specified netmask calculated from the prefix,
can be found in the set.
.PP
The \fBbitmap:ip\fR type supports adding or deleting multiple entries in one
@@ -270,19 +270,19 @@ ipset test foo 192.168.1.1
.SS bitmap:ip,mac
The \fBbitmap:ip,mac\fR set type uses a memory range to store IPv4 and a MAC address pairs. A \fBbitmap:ip,mac\fR type of set can store up to 65536 entries.
.PP
-\fICREATE\-OPTIONS\fR := \fBrange\fP \fIfrom\-ip\fP\-\fIto\-ip\fR|\fIip\fR/\fIcidr\fR [ \fBtimeout\fR \fIvalue\fR ]
+\fICREATE\-OPTIONS\fR := \fBrange\fP \fIfromip\fP\-\fItoip\fR|\fIip\fR/\fIcidr\fR [ \fBtimeout\fR \fIvalue\fR ]
.PP
-\fIADD\-ENTRY\fR := \fIipaddr\fR[,\fImac\-addr\fR]
+\fIADD\-ENTRY\fR := \fIipaddr\fR[,\fImacaddr\fR]
.PP
\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ]
.PP
-\fIDEL\-ENTRY\fR := \fIipaddr\fR[,\fImac\-addr\fR]
+\fIDEL\-ENTRY\fR := \fIipaddr\fR[,\fImacaddr\fR]
.PP
-\fITEST\-ENTRY\fR := \fIipaddr\fR[,\fImac\-addr\fR]
+\fITEST\-ENTRY\fR := \fIipaddr\fR[,\fImacaddr\fR]
.PP
Mandatory options to use when creating a \fBbitmap:ip,mac\fR type of set:
.TP
-\fBrange\fP \fIfrom\-ip\fP\-\fIto\-ip\fR|\fIip\fR/\fIcidr\fR
+\fBrange\fP \fIfromip\fP\-\fItoip\fR|\fIip\fR/\fIcidr\fR
Create the set from the specified inclusive address range expressed in an
IPv4 address range or network. The size of the range cannot exceed the limit
of maximum 65536 entries.
@@ -309,19 +309,19 @@ ipset test foo 192.168.1.1
The \fBbitmap:port\fR set type uses a memory range to store port numbers
and such a set can store up to 65536 ports.
.PP
-\fICREATE\-OPTIONS\fR := \fBrange\fP \fIfrom\-port\fP\-\fIto\-port [ \fBtimeout\fR \fIvalue\fR ]
+\fICREATE\-OPTIONS\fR := \fBrange\fP \fIfromport\fP\-\fItoport [ \fBtimeout\fR \fIvalue\fR ]
.PP
-\fIADD\-ENTRY\fR := { \fIport\fR | \fIfrom\-port\fR\-\fIto\-port\fR }
+\fIADD\-ENTRY\fR := { \fIport\fR | \fIfromport\fR\-\fItoport\fR }
.PP
\fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ]
.PP
-\fIDEL\-ENTRY\fR := { \fIport\fR | \fIfrom\-port\fR\-\fIto\-port\fR }
+\fIDEL\-ENTRY\fR := { \fIport\fR | \fIfromport\fR\-\fItoport\fR }
.PP
\fITEST\-ENTRY\fR := \fIport\fR
.PP
Mandatory options to use when creating a \fBbitmap:port\fR type of set:
.TP
-\fBrange\fP \fIfrom\-port\fP\-\fIto\-port\fR
+\fBrange\fP \fIfromport\fP\-\fItoport\fR
Create the set from the specified inclusive port range.
.PP
Examples:
@@ -368,10 +368,10 @@ The maximal number of elements which can be stored in the set, default 65536.
.TP
\fBnetmask\fP \fIcidr\fP
When the optional \fBnetmask\fP parameter specified, network addresses will be
-stored in the set instead of IP host addresses. The \fIcidr\fP value must be
+stored in the set instead of IP host addresses. The \fIcidr\fP prefix value must be
between 1\-32 for IPv4 and between 1\-128 for IPv6. An IP address will be in the set
if the network address, which is resulted by masking the address with the netmask
-calculated from the cidr, can be found in the set.
+calculated from the prefix, can be found in the set.
.PP
Examples:
.IP
@@ -407,18 +407,18 @@ correct value.
\fBmaxelem\fR \fIvalue\fR
The maximal number of elements which can be stored in the set, default 65536.
.PP
-When adding/deleting/testing entries, if the cidr parameter is not specified,
-then the host cidr value is assumed. When adding/deleting entries, overlapping elements
-are not checked.
+When adding/deleting/testing entries, if the cidr prefix parameter is not specified,
+then the host prefix value is assumed. When adding/deleting entries, overlapping
+elements are not checked.
.PP
From the \fBset\fR netfilter match point of view an IP address will be in a \fBhash:net\fR type of set if it belongs to any of the netblocks added to the set.
The matching always start from the smallest size of netblock (most specific
-cidr) to the largest ones (least specific cidr). When adding/deleting IP
+prefix) to the largest ones (least specific prefix). When adding/deleting IP
addresses to the set by the \fBSET\fR netfilter target, it will be
-added/deleted by the most specific cidr which can be found in the
-set, or by the host cidr value if the set is empty.
+added/deleted by the most specific prefix which can be found in the
+set, or by the host prefix value if the set is empty.
.PP
-The lookup time grows linearly with the number of the different \fIcidr\fR
+The lookup time grows linearly with the number of the different prefix
values added to the set.
.PP
Examples:
@@ -626,10 +626,12 @@ the match and target will skip any set in \fIa\fR and \fIb\fR
which stores data triples, but will match all sets with single or double
data storage in \fIa\fR set and stop matching at the first successful set,
and add src to the first single or src,dst to the first double data storage set
-in \fIb\fR to which the entry can be added.
+in \fIb\fR to which the entry can be added. You can imagine a \fBlist:set\fR
+type of set as an ordered union of the set elements.
.PP
-You can imagine a setlist type of set as an ordered union of
-the set elements.
+Please note: by the \fBipset\fR commad you can add, delete and \fBtest\fR
+the setnames in a \fBlist:set\fR type of set, and \fBnot\fR the presence of
+a set's member (such as an IP address).
.SH "GENERAL RESTRICTIONS"
Zero valued set entries cannot be used with hash methods. Zero protocol value with ports
cannot be used.
diff --git a/src/ipset.c b/src/ipset.c
index c613b24..c55bf59 100644
--- a/src/ipset.c
+++ b/src/ipset.c
@@ -38,10 +38,10 @@ extern struct ipset_type ipset_bitmap_ipmac0;
extern struct ipset_type ipset_bitmap_port0;
extern struct ipset_type ipset_hash_ip0;
extern struct ipset_type ipset_hash_net0;
+extern struct ipset_type ipset_hash_netport0;
extern struct ipset_type ipset_hash_ipport0;
extern struct ipset_type ipset_hash_ipportip0;
extern struct ipset_type ipset_hash_ipportnet0;
-extern struct ipset_type ipset_tree_ip0;
extern struct ipset_type ipset_list_set0;
enum exittype {
@@ -213,7 +213,8 @@ call_parser(int *argc, char *argv[], const struct ipset_arg *args)
goto done;
for (arg = args; arg->opt; arg++) {
for (i = 1; i < *argc; ) {
- D("argc: %u, i: %u: %s vs %s", *argc, i, argv[i], arg->name[0]);
+ D("argc: %u, i: %u: %s vs %s",
+ *argc, i, argv[i], arg->name[0]);
if (!(ipset_match_option(argv[i], arg->name))) {
i++;
continue;
@@ -227,7 +228,8 @@ call_parser(int *argc, char *argv[], const struct ipset_arg *args)
case IPSET_MANDATORY_ARG:
if (i + 1 > *argc)
return exit_error(PARAMETER_PROBLEM,
- "Missing mandatory argument of option `%s'",
+ "Missing mandatory argument "
+ "of option `%s'",
arg->name[0]);
/* Fall through */
case IPSET_OPTIONAL_ARG:
@@ -276,7 +278,8 @@ check_mandatory(const struct ipset_type *type, int cmd)
return;
if (!arg) {
exit_error(OTHER_PROBLEM,
- "There are missing mandatory flags but can't check them. "
+ "There are missing mandatory flags "
+ "but can't check them. "
"It's a bug, please report the problem.");
return;
}
@@ -354,7 +357,8 @@ parse_commandline(int argc, char *argv[])
case IPSET_MANDATORY_ARG:
if (i + 1 > argc)
return exit_error(PARAMETER_PROBLEM,
- "Missing mandatory argument to option %s",
+ "Missing mandatory argument "
+ "to option %s",
opt->name[0]);
/* Fall through */
case IPSET_OPTIONAL_ARG:
@@ -392,10 +396,13 @@ parse_commandline(int argc, char *argv[])
|| command->cmd == IPSET_CMD_VERSION
|| command->cmd == IPSET_CMD_HELP))
return exit_error(PARAMETER_PROBLEM,
- "Command `%s' is invalid in restore mode.",
+ "Command `%s' is invalid "
+ "in restore mode.",
command->name[0]);
- if (interactive && command->cmd == IPSET_CMD_RESTORE) {
- printf("Restore command ignored in interactive mode\n");
+ if (interactive
+ && command->cmd == IPSET_CMD_RESTORE) {
+ printf("Restore command ignored "
+ "in interactive mode\n");
return 0;
}
@@ -407,7 +414,8 @@ parse_commandline(int argc, char *argv[])
case IPSET_MANDATORY_ARG2:
if (i + 1 > argc)
return exit_error(PARAMETER_PROBLEM,
- "Missing mandatory argument to command %s",
+ "Missing mandatory argument "
+ "to command %s",
command->name[0]);
/* Fall through */
case IPSET_OPTIONAL_ARG:
@@ -422,7 +430,8 @@ parse_commandline(int argc, char *argv[])
if (command->has_arg == IPSET_MANDATORY_ARG2) {
if (i + 1 > argc)
return exit_error(PARAMETER_PROBLEM,
- "Missing second mandatory argument to command %s",
+ "Missing second mandatory "
+ "argument to command %s",
command->name[0]);
arg1 = argv[i];
/* Shift off second arg */
@@ -460,7 +469,8 @@ parse_commandline(int argc, char *argv[])
}
if (argc > 1)
return exit_error(PARAMETER_PROBLEM,
- "No command specified: unknown argument %s", argv[1]);
+ "No command specified: unknown argument %s",
+ argv[1]);
return exit_error(PARAMETER_PROBLEM, "No command specified.");
case IPSET_CMD_VERSION:
printf("%s v%s.\n", program_name, program_version);
@@ -480,16 +490,21 @@ parse_commandline(int argc, char *argv[])
"Unknown settype: `%s'", arg0);
printf("\n%s type specific options:\n\n%s",
type->name, type->usage);
+ if (type->usagefn)
+ type->usagefn();
if (type->family == AF_UNSPEC)
printf("\nType %s is family neutral.\n",
type->name);
else if (type->family == AF_INET46)
- printf("\nType %s supports INET and INET6.\n",
+ printf("\nType %s supports INET "
+ "and INET6.\n",
type->name);
else
- printf("\nType %s supports family %s only.\n",
+ printf("\nType %s supports family "
+ "%s only.\n",
type->name,
- type->family == AF_INET ? "INET" : "INET6");
+ type->family == AF_INET
+ ? "INET" : "INET6");
} else {
printf("\nSupported set types:\n");
type = ipset_types();
@@ -541,7 +556,8 @@ parse_commandline(int argc, char *argv[])
case IPSET_CMD_SAVE:
/* Args: [setname] */
if (arg0) {
- ret = ipset_parse_setname(session, IPSET_SETNAME, arg0);
+ ret = ipset_parse_setname(session,
+ IPSET_SETNAME, arg0);
if (ret < 0)
return handle_error();
}
@@ -622,6 +638,7 @@ main(int argc, char *argv[])
ipset_type_add(&ipset_bitmap_port0);
ipset_type_add(&ipset_hash_ip0);
ipset_type_add(&ipset_hash_net0);
+ ipset_type_add(&ipset_hash_netport0);
ipset_type_add(&ipset_hash_ipport0);
ipset_type_add(&ipset_hash_ipportip0);
ipset_type_add(&ipset_hash_ipportnet0);
diff --git a/src/ipset_bitmap_ip.c b/src/ipset_bitmap_ip.c
index e28432b..4194875 100644
--- a/src/ipset_bitmap_ip.c
+++ b/src/ipset_bitmap_ip.c
@@ -52,7 +52,9 @@ static const char bitmap_ip_usage[] =
" [netmask CIDR] [timeout VALUE]\n"
"add SETNAME IP|IP/CIDR|FROM-TO [timeout VALUE]\n"
"del SETNAME IP|IP/CIDR|FROM-TO\n"
-"test SETNAME IP\n";
+"test SETNAME IP\n\n"
+"where IP, FROM and TO are IPv4 addresses (or hostnames),\n"
+" CIDR is a valid IPv4 CIDR prefix.\n";
struct ipset_type ipset_bitmap_ip0 = {
.name = "bitmap:ip",
diff --git a/src/ipset_bitmap_ipmac.c b/src/ipset_bitmap_ipmac.c
index 382ebb5..8f2cb72 100644
--- a/src/ipset_bitmap_ipmac.c
+++ b/src/ipset_bitmap_ipmac.c
@@ -48,7 +48,10 @@ static const char bitmap_ipmac_usage[] =
" [matchunset] [timeout VALUE]\n"
"add SETNAME IP[,MAC] [timeout VALUE]\n"
"del SETNAME IP[,MAC]\n"
-"test SETNAME IP[,MAC]\n";
+"test SETNAME IP[,MAC]\n\n"
+"where IP, FROM and TO are IPv4 addresses (or hostnames),\n"
+" CIDR is a valid IPv4 CIDR prefix,\n"
+" MAC is a valid MAC address.\n";
struct ipset_type ipset_bitmap_ipmac0 = {
.name = "bitmap:ip,mac",
diff --git a/src/ipset_bitmap_port.c b/src/ipset_bitmap_port.c
index 7871891..82b98a4 100644
--- a/src/ipset_bitmap_port.c
+++ b/src/ipset_bitmap_port.c
@@ -13,7 +13,7 @@
static const struct ipset_arg bitmap_port_create_args[] = {
{ .name = { "range", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PORT,
- .parse = ipset_parse_port, .print = ipset_print_port,
+ .parse = ipset_parse_tcp_port, .print = ipset_print_port,
},
{ .name = { "timeout", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
@@ -22,11 +22,11 @@ static const struct ipset_arg bitmap_port_create_args[] = {
/* Backward compatibility */
{ .name = { "from", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PORT,
- .parse = ipset_parse_single_port,
+ .parse = ipset_parse_single_tcp_port,
},
{ .name = { "to", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PORT_TO,
- .parse = ipset_parse_single_port,
+ .parse = ipset_parse_single_tcp_port,
},
{ },
};
@@ -44,7 +44,8 @@ static const char bitmap_port_usage[] =
" [timeout VALUE]\n"
"add SETNAME PORT|FROM-TO [timeout VALUE]\n"
"del SETNAME PORT|FROM-TO\n"
-"test SETNAME PORT\n";
+"test SETNAME PORT\n\n"
+"where PORT, FROM and TO are port numbers or port names from /etc/services.\n";
struct ipset_type ipset_bitmap_port0 = {
.name = "bitmap:port",
@@ -54,7 +55,7 @@ struct ipset_type ipset_bitmap_port0 = {
.dimension = IPSET_DIM_ONE,
.elem = {
[IPSET_DIM_ONE] = {
- .parse = ipset_parse_port,
+ .parse = ipset_parse_tcp_port,
.print = ipset_print_port,
.opt = IPSET_OPT_PORT
},
diff --git a/src/ipset_hash_ip.c b/src/ipset_hash_ip.c
index 6609eea..be64189 100644
--- a/src/ipset_hash_ip.c
+++ b/src/ipset_hash_ip.c
@@ -72,7 +72,10 @@ static const char hash_ip_usage[] =
" [netmask CIDR] [timeout VALUE]\n"
"add SETNAME IP|IP/CIDR|FROM-TO [timeout VALUE]\n"
"del SETNAME IP|IP/CIDR|FROM-TO\n"
-"test SETNAME IP\n";
+"test SETNAME IP\n\n"
+"where depending on the INET family\n"
+" IP, FROM and TO are IPv4 or IPv6 addresses (or hostnames),\n"
+" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n";
struct ipset_type ipset_hash_ip0 = {
.name = "hash:ip",
diff --git a/src/ipset_hash_ipport.c b/src/ipset_hash_ipport.c
index 94a8cc6..4b06d5e 100644
--- a/src/ipset_hash_ipport.c
+++ b/src/ipset_hash_ipport.c
@@ -7,6 +7,7 @@
#include <libipset/data.h> /* IPSET_OPT_* */
#include <libipset/parse.h> /* parser functions */
#include <libipset/print.h> /* printing functions */
+#include <libipset/ui.h> /* ipset_port_usage */
#include <libipset/types.h> /* prototypes */
/* Parse commandline arguments */
@@ -37,10 +38,6 @@ static const struct ipset_arg hash_ipport_create_args[] = {
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
.parse = ipset_parse_uint32, .print = ipset_print_number,
},
- { .name = { "proto", NULL },
- .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROTO,
- .parse = ipset_parse_proto, .print = ipset_print_proto,
- },
/* Backward compatibility */
{ .name = { "probes", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
@@ -75,12 +72,14 @@ static const struct ipset_arg hash_ipport_add_args[] = {
static const char hash_ipport_usage[] =
"create SETNAME hash:ip,port\n"
-" [family inet|inet6] [proto PROTO]\n"
+" [family inet|inet6]\n"
" [hashsize VALUE] [maxelem VALUE]\n"
" [timeout VALUE]\n"
-"add SETNAME IP,[PROTO:]PORT [timeout VALUE]\n"
-"del SETNAME IP,[PROTO:]PORT\n"
-"test SETNAME IP,[PROTO:]PORT\n";
+"add SETNAME IP,PROTO:PORT [timeout VALUE]\n"
+"del SETNAME IP,PROTO:PORT\n"
+"test SETNAME IP,PROTO:PORT\n\n"
+"where depending on the INET family\n"
+" IP is a valid IPv4 or IPv6 address (or hostname),\n";
struct ipset_type ipset_hash_ipport0 = {
.name = "hash:ip,port",
@@ -107,16 +106,18 @@ struct ipset_type ipset_hash_ipport0 = {
.mandatory = {
[IPSET_CREATE] = 0,
[IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_PORT),
[IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_PORT),
[IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_PORT),
},
.full = {
[IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
| IPSET_FLAG(IPSET_OPT_MAXELEM)
- | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_TIMEOUT),
[IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
| IPSET_FLAG(IPSET_OPT_PORT)
@@ -131,4 +132,5 @@ struct ipset_type ipset_hash_ipport0 = {
},
.usage = hash_ipport_usage,
+ .usagefn = ipset_port_usage,
};
diff --git a/src/ipset_hash_ipportip.c b/src/ipset_hash_ipportip.c
index dc121e4..5294da3 100644
--- a/src/ipset_hash_ipportip.c
+++ b/src/ipset_hash_ipportip.c
@@ -7,6 +7,7 @@
#include <libipset/data.h> /* IPSET_OPT_* */
#include <libipset/parse.h> /* parser functions */
#include <libipset/print.h> /* printing functions */
+#include <libipset/ui.h> /* ipset_port_usage */
#include <libipset/types.h> /* prototypes */
/* Parse commandline arguments */
@@ -37,10 +38,6 @@ static const struct ipset_arg hash_ipportip_create_args[] = {
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
.parse = ipset_parse_uint32, .print = ipset_print_number,
},
- { .name = { "proto", NULL },
- .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROTO,
- .parse = ipset_parse_proto, .print = ipset_print_proto,
- },
/* Backward compatibility */
{ .name = { "probes", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
@@ -75,12 +72,14 @@ static const struct ipset_arg hash_ipportip_add_args[] = {
static const char hash_ipportip_usage[] =
"create SETNAME hash:ip,port,ip\n"
-" [family inet|inet6] [proto PROTO]\n"
+" [family inet|inet6]\n"
" [hashsize VALUE] [maxelem VALUE]\n"
" [timeout VALUE]\n"
-"add SETNAME IP,[PROTO:]PORT,IP [timeout VALUE]\n"
-"del SETNAME IP,[PROTO:]PORT,IP\n"
-"test SETNAME IP,[PROTO:]PORT,IP\n";
+"add SETNAME IP,PROTO:PORT,IP [timeout VALUE]\n"
+"del SETNAME IP,PROTO:PORT,IP\n"
+"test SETNAME IP,PROTO:PORT,IP\n\n"
+"where depending on the INET family\n"
+" IP are valid IPv4 or IPv6 addresses (or hostnames),\n";
struct ipset_type ipset_hash_ipportip0 = {
.name = "hash:ip,port,ip",
@@ -113,18 +112,20 @@ struct ipset_type ipset_hash_ipportip0 = {
[IPSET_CREATE] = 0,
[IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
| IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_IP2),
[IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
| IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_IP2),
[IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
| IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_IP2),
},
.full = {
[IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
| IPSET_FLAG(IPSET_OPT_MAXELEM)
- | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_TIMEOUT),
[IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
| IPSET_FLAG(IPSET_OPT_PORT)
@@ -142,4 +143,5 @@ struct ipset_type ipset_hash_ipportip0 = {
},
.usage = hash_ipportip_usage,
+ .usagefn = ipset_port_usage,
};
diff --git a/src/ipset_hash_ipportnet.c b/src/ipset_hash_ipportnet.c
index a668c5e..3c073cd 100644
--- a/src/ipset_hash_ipportnet.c
+++ b/src/ipset_hash_ipportnet.c
@@ -7,6 +7,7 @@
#include <libipset/data.h> /* IPSET_OPT_* */
#include <libipset/parse.h> /* parser functions */
#include <libipset/print.h> /* printing functions */
+#include <libipset/ui.h> /* ipset_port_usage */
#include <libipset/types.h> /* prototypes */
/* Parse commandline arguments */
@@ -37,10 +38,6 @@ static const struct ipset_arg hash_ipportnet_create_args[] = {
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
.parse = ipset_parse_uint32, .print = ipset_print_number,
},
- { .name = { "proto", NULL },
- .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROTO,
- .parse = ipset_parse_proto, .print = ipset_print_proto,
- },
/* Backward compatibility */
{ .name = { "probes", NULL },
.has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_PROBES,
@@ -75,12 +72,15 @@ static const struct ipset_arg hash_ipportnet_add_args[] = {
static const char hash_ipportnet_usage[] =
"create SETNAME hash:ip,port,net\n"
-" [family inet|inet6] [proto PROTO]\n"
+" [family inet|inet6]\n"
" [hashsize VALUE] [maxelem VALUE]\n"
" [timeout VALUE]\n"
-"add SETNAME IP,[PROTO:]PORT,IP[/CIDR] [timeout VALUE]\n"
-"del SETNAME IP,[PROTO:]PORT,IP[/CIDR]\n"
-"test SETNAME IP,[PROTO:]PORT,IP[/CIDR]\n";
+"add SETNAME IP,PROTO:PORT,IP[/CIDR] [timeout VALUE]\n"
+"del SETNAME IP,PROTO:PORT,IP[/CIDR]\n"
+"test SETNAME IP,PROTO:PORT,IP[/CIDR]\n\n"
+"where depending on the INET family\n"
+" IP are valid IPv4 or IPv6 addresses (or hostnames),\n"
+" CIDR is a valid IPv4 or IPv6 CIDR prefix,\n";
struct ipset_type ipset_hash_ipportnet0 = {
.name = "hash:ip,port,net",
@@ -113,18 +113,20 @@ struct ipset_type ipset_hash_ipportnet0 = {
[IPSET_CREATE] = 0,
[IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
| IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_IP2),
[IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
| IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_IP2),
[IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
| IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_IP2),
},
.full = {
[IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
| IPSET_FLAG(IPSET_OPT_MAXELEM)
- | IPSET_FLAG(IPSET_OPT_PROTO)
| IPSET_FLAG(IPSET_OPT_TIMEOUT),
[IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
| IPSET_FLAG(IPSET_OPT_PORT)
@@ -145,4 +147,5 @@ struct ipset_type ipset_hash_ipportnet0 = {
},
.usage = hash_ipportnet_usage,
+ .usagefn = ipset_port_usage,
};
diff --git a/src/ipset_hash_net.c b/src/ipset_hash_net.c
index c14652d..e8891c1 100644
--- a/src/ipset_hash_net.c
+++ b/src/ipset_hash_net.c
@@ -64,7 +64,10 @@ static const char hash_net_usage[] =
" [timeout VALUE]\n"
"add SETNAME IP[/CIDR] [timeout VALUE]\n"
"del SETNAME IP[/CIDR]\n"
-"test SETNAME IP[/CIDR]\n";
+"test SETNAME IP[/CIDR]\n\n"
+"where depending on the INET family\n"
+" IP is an IPv4 or IPv6 address (or hostname),\n"
+" CIDR is a valid IPv4 or IPv6 CIDR prefix.\n";
struct ipset_type ipset_hash_net0 = {
.name = "hash:net",
diff --git a/src/ipset_hash_netport.c b/src/ipset_hash_netport.c
new file mode 100644
index 0000000..934162a
--- /dev/null
+++ b/src/ipset_hash_netport.c
@@ -0,0 +1,119 @@
+/* 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 <libipset/data.h> /* IPSET_OPT_* */
+#include <libipset/parse.h> /* parser functions */
+#include <libipset/print.h> /* printing functions */
+#include <libipset/ui.h> /* ipset_port_usage */
+#include <libipset/types.h> /* prototypes */
+
+/* Parse commandline arguments */
+static const struct ipset_arg hash_netport_create_args[] = {
+ { .name = { "family", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family, .print = ipset_print_family,
+ },
+ /* Alias: family inet */
+ { .name = { "-4", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family,
+ },
+ /* Alias: family inet6 */
+ { .name = { "-6", NULL },
+ .has_arg = IPSET_NO_ARG, .opt = IPSET_OPT_FAMILY,
+ .parse = ipset_parse_family,
+ },
+ { .name = { "hashsize", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_HASHSIZE,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { .name = { "maxelem", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_MAXELEM,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { .name = { "timeout", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { },
+};
+
+static const struct ipset_arg hash_netport_add_args[] = {
+ { .name = { "timeout", NULL },
+ .has_arg = IPSET_MANDATORY_ARG, .opt = IPSET_OPT_TIMEOUT,
+ .parse = ipset_parse_uint32, .print = ipset_print_number,
+ },
+ { },
+};
+
+static const char hash_netport_usage[] =
+"create SETNAME hash:net,port\n"
+" [family inet|inet6]\n"
+" [hashsize VALUE] [maxelem VALUE]\n"
+" [timeout VALUE]\n"
+"add SETNAME IP[/CIDR],PROTO:PORT [timeout VALUE]\n"
+"del SETNAME IP[/CIDR],PROTO:PORT\n"
+"test SETNAME IP[/CIDR],PROTO:PORT\n\n"
+"where depending on the INET family\n"
+" IP is a valid IPv4 or IPv6 address (or hostname),\n"
+" CIDR is a valid IPv4 or IPv6 CIDR prefix,\n";
+
+struct ipset_type ipset_hash_netport0 = {
+ .name = "hash:net,port",
+ .alias = { "netporthash", NULL },
+ .revision = 0,
+ .family = AF_INET46,
+ .dimension = IPSET_DIM_TWO,
+ .elem = {
+ [IPSET_DIM_ONE] = {
+ .parse = ipset_parse_ipnet,
+ .print = ipset_print_ip,
+ .opt = IPSET_OPT_IP
+ },
+ [IPSET_DIM_TWO] = {
+ .parse = ipset_parse_proto_port,
+ .print = ipset_print_proto_port,
+ .opt = IPSET_OPT_PORT
+ },
+ },
+ .args = {
+ [IPSET_CREATE] = hash_netport_create_args,
+ [IPSET_ADD] = hash_netport_add_args,
+ },
+ .mandatory = {
+ [IPSET_CREATE] = 0,
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_PORT),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_PORT),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_PORT),
+ },
+ .full = {
+ [IPSET_CREATE] = IPSET_FLAG(IPSET_OPT_HASHSIZE)
+ | IPSET_FLAG(IPSET_OPT_MAXELEM)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT),
+ [IPSET_ADD] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_TIMEOUT)
+ | IPSET_FLAG(IPSET_OPT_CIDR),
+ [IPSET_DEL] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_CIDR),
+ [IPSET_TEST] = IPSET_FLAG(IPSET_OPT_IP)
+ | IPSET_FLAG(IPSET_OPT_PORT)
+ | IPSET_FLAG(IPSET_OPT_PROTO)
+ | IPSET_FLAG(IPSET_OPT_CIDR),
+ },
+
+ .usage = hash_netport_usage,
+ .usagefn = ipset_port_usage,
+};
diff --git a/src/ipset_list_set.c b/src/ipset_list_set.c
index 76cf9b2..d0b0dd6 100644
--- a/src/ipset_list_set.c
+++ b/src/ipset_list_set.c
@@ -43,7 +43,8 @@ static const char list_set_usage[] =
" [size VALUE] [timeout VALUE]\n"
"add SETNAME NAME [before|after NAME] [timeout VALUE]\n"
"del SETNAME NAME\n"
-"test SETNAME NAME\n";
+"test SETNAME NAME\n\n"
+"where NAME are existing set names.\n";
struct ipset_type ipset_list_set0 = {
.name = "list:set",
diff --git a/src/ui.c b/src/ui.c
index d8face5..ce90532 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -9,6 +9,8 @@
#include <string.h> /* memcmp, str* */
#include <libipset/linux_ip_set.h> /* IPSET_CMD_* */
+#include <libipset/icmp.h> /* id_to_icmp */
+#include <libipset/icmpv6.h> /* id_to_icmpv6 */
#include <libipset/types.h> /* IPSET_*_ARG */
#include <libipset/session.h> /* ipset_envopt_parse */
#include <libipset/parse.h> /* ipset_parse_family */
@@ -141,7 +143,7 @@ ipset_match_cmd(const char *arg, const char * const name[])
if (len > strlen(name[0]) || !len)
return false;
- else if (memcmp(arg, name[0], len) == 0)
+ else if (strcmp(arg, name[0]) == 0)
return true;
else if (len != 1)
return false;
@@ -242,3 +244,33 @@ ipset_shift_argv(int *argc, char *argv[], int from)
return;
}
+/**
+ * ipset_port_usage - prints the usage for the port parameter
+ *
+ * Print the usage for the port parameter to stdout.
+ */
+void
+ipset_port_usage(void)
+{
+ int i;
+ const char *name;
+
+ printf(" [PROTO:]PORT is a valid pattern of the following:\n"
+ " PORTNAME port name from /etc/services\n"
+ " PORTNUMBER port number identifier\n"
+ " tcp|udp:PORTNAME|PORTNUMBER\n"
+ " icmp:CODENAME supported ICMP codename\n"
+ " icmp:TYPE/CODE ICMP type/code value\n"
+ " icmpv6:CODENAME supported ICMPv6 codename\n"
+ " icmpv6:TYPE/CODE ICMPv6 type/code value\n"
+ " PROTO:0 all other protocols\n\n");
+
+ printf(" Supported ICMP codenames:\n");
+ i = 0;
+ while ((name = id_to_icmp(i++)) != NULL)
+ printf(" %s\n", name);
+ printf(" Supported ICMPv6 codenames:\n");
+ i = 0;
+ while ((name = id_to_icmpv6(i++)) != NULL)
+ printf(" %s\n", name);
+}