From 480761a3bdaa55bf8c966e4dab950ebf84775863 Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Fri, 9 Aug 2013 12:26:33 +0100 Subject: Add specifying protocol for bitmap:port Signed-off-by: Jozsef Kadlecsik --- lib/ipset_bitmap_port.c | 32 ++++++++++++++++++-------------- lib/parse.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 14 deletions(-) (limited to 'lib') diff --git a/lib/ipset_bitmap_port.c b/lib/ipset_bitmap_port.c index 6959c3a..a706d80 100644 --- a/lib/ipset_bitmap_port.c +++ b/lib/ipset_bitmap_port.c @@ -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 }, diff --git a/lib/parse.c b/lib/parse.c index ce3548d..112b273 100644 --- a/lib/parse.c +++ b/lib/parse.c @@ -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 -- cgit v1.2.3