From 0d32c5c070f817229110f92d7b31df9a3e4eeec5 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Sun, 24 Oct 2010 21:42:48 +0200 Subject: Fixes, cleanups, comments - 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) --- lib/print.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 5 deletions(-) (limited to 'lib/print.c') diff --git a/lib/print.c b/lib/print.c index 77c283a..87a9f2b 100644 --- a/lib/print.c +++ b/lib/print.c @@ -15,6 +15,8 @@ #include /* D() */ #include /* ipset_data_* */ +#include /* icmp_to_name */ +#include /* icmpv6_to_name */ #include /* IPSET_*_SEPARATOR */ #include /* ipset set types */ #include /* IPSET_FLAG_ */ @@ -463,8 +465,6 @@ ipset_print_proto(char *buf, unsigned int len, proto = *(const uint8_t *) ipset_data_get(data, IPSET_OPT_PROTO); assert(proto); - if (proto == IPSET_IPPROTO_ANY) - return snprintf(buf, len, "any"); protoent = getprotobynumber(proto); if (protoent) return snprintf(buf, len, "%s", protoent->p_name); @@ -473,6 +473,72 @@ ipset_print_proto(char *buf, unsigned int len, return snprintf(buf, len, "%u", proto); } +/** + * ipset_print_icmp - print ICMP code name or type/code + * @buf: printing buffer + * @len: length of available buffer space + * @data: data blob + * @opt: the option kind + * @env: environment flags + * + * Print ICMP code name or type/code name to output buffer. + * + * Return lenght of printed string or error size. + */ +int +ipset_print_icmp(char *buf, unsigned int len, + const struct ipset_data *data, enum ipset_opt opt, + uint8_t env UNUSED) +{ + const char *name; + uint16_t typecode; + + assert(buf); + assert(len > 0); + assert(data); + assert(opt == IPSET_OPT_PORT); + + typecode = *(const uint16_t *) ipset_data_get(data, IPSET_OPT_PORT); + name = icmp_to_name(typecode >> 8, typecode & 0xFF); + if (name != NULL) + return snprintf(buf, len, "%s", name); + else + return snprintf(buf, len, "%u/%u", typecode >> 8, typecode & 0xFF); +} + +/** + * ipset_print_icmpv6 - print ICMPv6 code name or type/code + * @buf: printing buffer + * @len: length of available buffer space + * @data: data blob + * @opt: the option kind + * @env: environment flags + * + * Print ICMPv6 code name or type/code name to output buffer. + * + * Return lenght of printed string or error size. + */ +int +ipset_print_icmpv6(char *buf, unsigned int len, + const struct ipset_data *data, enum ipset_opt opt, + uint8_t env UNUSED) +{ + const char *name; + uint16_t typecode; + + assert(buf); + assert(len > 0); + assert(data); + assert(opt == IPSET_OPT_PORT); + + typecode = *(const uint16_t *) ipset_data_get(data, IPSET_OPT_PORT); + name = icmpv6_to_name(typecode >> 8, typecode & 0xFF); + if (name != NULL) + return snprintf(buf, len, "%s", name); + else + return snprintf(buf, len, "%u/%u", typecode >> 8, typecode & 0xFF); +} + /** * ipset_print_proto_port - print proto:port * @buf: printing buffer @@ -498,14 +564,33 @@ ipset_print_proto_port(char *buf, unsigned int len, assert(opt == IPSET_OPT_PORT); if (ipset_data_flags_test(data, IPSET_FLAG(IPSET_OPT_PROTO))) { + uint8_t proto = *(const uint8_t *) ipset_data_get(data, + IPSET_OPT_PROTO); size = ipset_print_proto(buf, len, data, IPSET_OPT_PROTO, env); SNPRINTF_FAILURE(size, len, offset); if (len < 2) return -ENOSPC; - strcat(buf, ":"); - SNPRINTF_FAILURE(1, len, offset); + size = snprintf(buf + offset, len, IPSET_PROTO_SEPARATOR); + SNPRINTF_FAILURE(size, len, offset); + + switch (proto) { + case IPPROTO_TCP: + case IPPROTO_UDP: + break; + case IPPROTO_ICMP: + return ipset_print_icmp(buf + offset, len, data, + IPSET_OPT_PORT, env); + case IPPROTO_ICMPV6: + return ipset_print_icmpv6(buf + offset, len, data, + IPSET_OPT_PORT, env); + default: + break; + } } - return ipset_print_port(buf + offset, len, data, IPSET_OPT_PORT, env); + size = ipset_print_port(buf + offset, len, data, IPSET_OPT_PORT, env); + SNPRINTF_FAILURE(size, len, offset); + + return offset; } #define print_second(data) \ -- cgit v1.2.3