]> granicus.if.org Git - ipset/commitdiff
Add specifying protocol for bitmap:port
authorQuentin Armitage <quentin@armitage.org.uk>
Fri, 9 Aug 2013 11:26:33 +0000 (12:26 +0100)
committerJozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Sat, 17 Aug 2013 19:31:29 +0000 (21:31 +0200)
Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
include/libipset/parse.h
lib/ipset_bitmap_port.c
lib/parse.c
src/ipset.8

index ee16fb53adb4acd26acc91428d7a3d4fd95bef33..014c62f706015ec9e9eda8c489926f237aff440c 100644 (file)
@@ -44,6 +44,8 @@ extern int ipset_parse_icmpv6(struct ipset_session *session,
                              enum ipset_opt opt, const char *str);
 extern int ipset_parse_proto_port(struct ipset_session *session,
                                  enum ipset_opt opt, const char *str);
+extern int ipset_parse_tcp_udp_port(struct ipset_session *session,
+                                 enum ipset_opt opt, const char *str);
 extern int ipset_parse_family(struct ipset_session *session,
                              enum ipset_opt opt, const char *str);
 extern int ipset_parse_ip(struct ipset_session *session,
index 6959c3a17bd3b0559ad128d5a933b3e360b8240e..a706d80e220416e4bf919ca419377db92c9371e9 100644 (file)
@@ -13,7 +13,7 @@
 static const struct ipset_arg bitmap_port_create_args0[] = {
        { .name = { "range", NULL },
          .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PORT,
-         .parse = ipset_parse_tcp_port,        .print = ipset_print_port,
+         .parse = ipset_parse_tcp_udp_port,    .print = ipset_print_port,
        },
        { .name = { "timeout", NULL },
          .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
@@ -40,12 +40,14 @@ static const struct ipset_arg bitmap_port_add_args0[] = {
 };
 
 static const char bitmap_port_usage0[] =
-"create SETNAME bitmap:port range FROM-TO\n"
+"create SETNAME bitmap:port range [PROTO:]FROM-TO\n"
 "               [timeout VALUE]\n"
-"add    SETNAME PORT|FROM-TO [timeout VALUE]\n"
-"del    SETNAME PORT|FROM-TO\n"
-"test   SETNAME PORT\n\n"
-"where PORT, FROM and TO are port numbers or port names from /etc/services.\n";
+"add    SETNAME [PROTO:]PORT|FROM-TO [timeout VALUE]\n"
+"del    SETNAME [PROTO:]PORT|FROM-TO\n"
+"test   SETNAME [PROTO:]PORT\n\n"
+"where PORT, FROM and TO are port numbers or port names from /etc/services.\n"
+"PROTO is only needed if a service name is used and it does not exist as a TCP service;\n"
+"it isn't used otherwise with the bitmap.\n";
 
 static struct ipset_type ipset_bitmap_port0 = {
        .name = "bitmap:port",
@@ -55,7 +57,7 @@ static struct ipset_type ipset_bitmap_port0 = {
        .dimension = IPSET_DIM_ONE,
        .elem = {
                [IPSET_DIM_ONE - 1] = {
-                       .parse = ipset_parse_tcp_port,
+                       .parse = ipset_parse_tcp_udp_port,
                        .print = ipset_print_port,
                        .opt = IPSET_OPT_PORT
                },
@@ -91,7 +93,7 @@ static struct ipset_type ipset_bitmap_port0 = {
 static const struct ipset_arg bitmap_port_create_args1[] = {
        { .name = { "range", NULL },
          .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_PORT,
-         .parse = ipset_parse_tcp_port,        .print = ipset_print_port,
+         .parse = ipset_parse_tcp_udp_port,    .print = ipset_print_port,
        },
        { .name = { "timeout", NULL },
          .has_arg = IPSET_MANDATORY_ARG,       .opt = IPSET_OPT_TIMEOUT,
@@ -130,13 +132,15 @@ static const struct ipset_arg bitmap_port_add_args1[] = {
 };
 
 static const char bitmap_port_usage1[] =
-"create SETNAME bitmap:port range FROM-TO\n"
+"create SETNAME bitmap:port range [PROTO:]FROM-TO\n"
 "               [timeout VALUE] [counters]\n"
-"add    SETNAME PORT|FROM-TO [timeout VALUE]\n"
+"add    SETNAME [PROTO:]PORT|FROM-TO [timeout VALUE]\n"
 "               [packets VALUE] [bytes VALUE]\n"
-"del    SETNAME PORT|FROM-TO\n"
-"test   SETNAME PORT\n\n"
-"where PORT, FROM and TO are port numbers or port names from /etc/services.\n";
+"del    SETNAME [PROTO:]PORT|FROM-TO\n"
+"test   SETNAME [PROTO:]PORT\n\n"
+"where PORT, FROM and TO are port numbers or port names from /etc/services.\n"
+"PROTO is only needed if a service name is used and it does not exist as a TCP service;\n"
+"it isn't used otherwise with the bitmap.\n";
 
 static struct ipset_type ipset_bitmap_port1 = {
        .name = "bitmap:port",
@@ -146,7 +150,7 @@ static struct ipset_type ipset_bitmap_port1 = {
        .dimension = IPSET_DIM_ONE,
        .elem = {
                [IPSET_DIM_ONE - 1] = {
-                       .parse = ipset_parse_tcp_port,
+                       .parse = ipset_parse_tcp_udp_port,
                        .print = ipset_print_port,
                        .opt = IPSET_OPT_PORT
                },
index ce3548d369f1eef901b121f15c03bdc2cb7476ad..112b27302100cc7a4cc1e40f8e902ab1ba4952fa 100644 (file)
@@ -636,6 +636,44 @@ error:
        return err;
 }
 
+/**
+ * ipset_parse_tcp_udp_port - parse (optional) protocol and a single port
+ * @session: session structure
+ * @opt: option kind of the data
+ * @str: string to parse
+ *
+ * Parse string as a protocol and port, separated by a colon.
+ * The protocol part is optional, but may only be "tcp" or "udp".
+ * The parsed port numbers are stored in the data
+ * blob of the session.
+ *
+ * Returns 0 on success or a negative error code.
+ */
+int
+ipset_parse_tcp_udp_port(struct ipset_session *session,
+                        enum ipset_opt opt, const char *str)
+{
+       struct ipset_data *data;
+       int err = 0;
+       uint8_t p = 0;
+
+       err = ipset_parse_proto_port(session, opt, str);
+
+       if (!err) {
+               data = ipset_session_data(session);
+
+               p = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_PROTO);
+               if (p != IPPROTO_TCP && p != IPPROTO_UDP) {
+                       syntax_err("Only protocols TCP and UDP are valid");
+                       err = -1 ;
+               } else {
+                       /* Reset the protocol to none */
+                       ipset_data_flags_unset(data, IPSET_FLAG(IPSET_OPT_PROTO));
+               }
+       }
+       return err;
+}
+
 /**
  * ipset_parse_family - parse INET|INET6 family names
  * @session: session structure
index 4353b9ffa30b0898ed3d4e73d14ee19a6e6ed35a..d7fa9645f638cc379a91063031a5ed6f3af0a31f 100644 (file)
@@ -391,22 +391,25 @@ and such a set can store up to 65536 ports.
 .PP 
 \fICREATE\-OPTIONS\fR := \fBrange\fP \fIfromport\fP\-\fItoport [ \fBtimeout\fR \fIvalue\fR ] [ \fBcounters\fP ]
 .PP 
-\fIADD\-ENTRY\fR := { \fIport\fR | \fIfromport\fR\-\fItoport\fR }
+\fIADD\-ENTRY\fR := { \fI[proto:]port\fR | \fI[proto:]fromport\fR\-\fItoport\fR }
 .PP 
 \fIADD\-OPTIONS\fR := [ \fBtimeout\fR \fIvalue\fR ] [ \fBpackets\fR \fIvalue\fR ] [ \fBbytes\fR \fIvalue\fR ]
 .PP 
-\fIDEL\-ENTRY\fR := { \fIport\fR | \fIfromport\fR\-\fItoport\fR }
+\fIDEL\-ENTRY\fR := { \fI[proto:]port\fR | \fI[proto:]fromport\fR\-\fItoport\fR }
 .PP 
-\fITEST\-ENTRY\fR := \fIport\fR
+\fITEST\-ENTRY\fR := \fI[proto:]port\fR
 .PP 
 Mandatory options to use when creating a \fBbitmap:port\fR type of set:
 .TP 
-\fBrange\fP \fIfromport\fP\-\fItoport\fR
+\fBrange\fP \fI[proto:]fromport\fP\-\fItoport\fR
 Create the set from the specified inclusive port range.
 .PP 
 The \fBset\fR match and \fBSET\fR target netfilter kernel modules interpret
 the stored numbers as TCP or UDP port numbers.
 .PP 
+\fBproto\fR only needs to be specified if a service name is used,
+and that name does not exist as a TCP service.
+.PP
 Examples:
 .IP 
 ipset create foo bitmap:port range 0\-1024
@@ -414,6 +417,8 @@ ipset create foo bitmap:port range 0\-1024
 ipset add foo 80
 .IP 
 ipset test foo 80
+.IP
+ipset del foo udp:[macon-udp]-[tn-tl-w2]
 .SS hash:ip
 The \fBhash:ip\fR set type uses a hash to store IP host addresses (default) or
 network addresses. Zero valued IP address cannot be stored in a \fBhash:ip\fR