From c5e5b784fd1a919b8dd34a4d9e88c8d022f259bf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 4 Mar 2018 09:28:56 +0100 Subject: Move ICMP type handling functions from ebt_ip6 to useful_functions.c Allow using these functions for ebt_ip as well. Signed-off-by: Matthias Schiffer Signed-off-by: Pablo Neira Ayuso --- extensions/ebt_ip6.c | 165 +++------------------------------------------------ 1 file changed, 9 insertions(+), 156 deletions(-) (limited to 'extensions') diff --git a/extensions/ebt_ip6.c b/extensions/ebt_ip6.c index dd48547..347797b 100644 --- a/extensions/ebt_ip6.c +++ b/extensions/ebt_ip6.c @@ -11,9 +11,6 @@ * */ -#include -#include -#include #include #include #include @@ -51,13 +48,7 @@ static const struct option opts[] = }; -struct icmpv6_names { - const char *name; - uint8_t type; - uint8_t code_min, code_max; -}; - -static const struct icmpv6_names icmpv6_codes[] = { +static const struct ebt_icmp_names icmpv6_codes[] = { { "destination-unreachable", 1, 0, 0xFF }, { "no-route", 1, 0, 0 }, { "communication-prohibited", 1, 1, 1 }, @@ -141,97 +132,6 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports) free(buffer); } -static char* -parse_num(const char *str, long min, long max, long *num) -{ - char *end; - - errno = 0; - *num = strtol(str, &end, 10); - if (errno && (*num == LONG_MIN || *num == LONG_MAX)) { - ebt_print_error("Invalid number %s: %s", str, strerror(errno)); - return NULL; - } - if (min <= max) { - if (*num > max || *num < min) { - ebt_print_error("Value %ld out of range (%ld, %ld)", *num, min, max); - return NULL; - } - } - if (*num == 0 && str == end) - return NULL; - return end; -} - -static char * -parse_range(const char *str, long min, long max, long num[]) -{ - char *next; - - next = parse_num(str, min, max, num); - if (next == NULL) - return NULL; - if (next && *next == ':') - next = parse_num(next+1, min, max, &num[1]); - else - num[1] = num[0]; - return next; -} - -static int -parse_icmpv6(const char *icmpv6type, uint8_t type[], uint8_t code[]) -{ - static const unsigned int limit = ARRAY_SIZE(icmpv6_codes); - unsigned int match = limit; - unsigned int i; - long number[2]; - - for (i = 0; i < limit; i++) { - if (strncasecmp(icmpv6_codes[i].name, icmpv6type, strlen(icmpv6type))) - continue; - if (match != limit) - ebt_print_error("Ambiguous ICMPv6 type `%s':" - " `%s' or `%s'?", - icmpv6type, icmpv6_codes[match].name, - icmpv6_codes[i].name); - match = i; - } - - if (match < limit) { - type[0] = type[1] = icmpv6_codes[match].type; - code[0] = icmpv6_codes[match].code_min; - code[1] = icmpv6_codes[match].code_max; - } else { - char *next = parse_range(icmpv6type, 0, 255, number); - if (!next) { - ebt_print_error("Unknown ICMPv6 type `%s'", - icmpv6type); - return -1; - } - type[0] = (uint8_t) number[0]; - type[1] = (uint8_t) number[1]; - switch (*next) { - case 0: - code[0] = 0; - code[1] = 255; - return 0; - case '/': - next = parse_range(next+1, 0, 255, number); - code[0] = (uint8_t) number[0]; - code[1] = (uint8_t) number[1]; - if (next == NULL) - return -1; - if (next && *next == 0) - return 0; - /* fallthrough */ - default: - ebt_print_error("unknown character %c", *next); - return -1; - } - } - return 0; -} - static void print_port_range(uint16_t *ports) { if (ports[0] == ports[1]) @@ -240,58 +140,6 @@ static void print_port_range(uint16_t *ports) printf("%d:%d ", ports[0], ports[1]); } -static void print_icmp_code(uint8_t *code) -{ - if (code[0] == code[1]) - printf("/%"PRIu8 " ", code[0]); - else - printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]); -} - -static void print_icmp_type(uint8_t *type, uint8_t *code) -{ - unsigned int i; - - if (type[0] != type[1]) { - printf("%"PRIu8 ":%" PRIu8, type[0], type[1]); - print_icmp_code(code); - return; - } - - for (i = 0; i < ARRAY_SIZE(icmpv6_codes); i++) { - if (icmpv6_codes[i].type != type[0]) - continue; - - if (icmpv6_codes[i].code_min == code[0] && - icmpv6_codes[i].code_max == code[1]) { - printf("%s ", icmpv6_codes[i].name); - return; - } - } - printf("%"PRIu8, type[0]); - print_icmp_code(code); -} - -static void print_icmpv6types(void) -{ - unsigned int i; - printf("Valid ICMPv6 Types:"); - - for (i=0; i < ARRAY_SIZE(icmpv6_codes); i++) { - if (i && icmpv6_codes[i].type == icmpv6_codes[i-1].type) { - if (icmpv6_codes[i].code_min == icmpv6_codes[i-1].code_min - && (icmpv6_codes[i].code_max - == icmpv6_codes[i-1].code_max)) - printf(" (%s)", icmpv6_codes[i].name); - else - printf("\n %s", icmpv6_codes[i].name); - } - else - printf("\n%s", icmpv6_codes[i].name); - } - printf("\n"); -} - static void print_help() { printf( @@ -303,7 +151,9 @@ static void print_help() "--ip6-sport [!] port[:port] : tcp/udp source port or port range\n" "--ip6-dport [!] port[:port] : tcp/udp destination port or port range\n" "--ip6-icmp-type [!] type[[:type]/code[:code]] : ipv6-icmp type/code or type/code range\n"); -print_icmpv6types(); + + printf("\nValid ICMPv6 Types:\n"); + ebt_print_icmp_types(icmpv6_codes, ARRAY_SIZE(icmpv6_codes)); } static void init(struct ebt_entry_match *match) @@ -374,7 +224,9 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry, ipinfo->bitmask |= EBT_IP6_ICMP6; if (ebt_check_inverse2(optarg)) ipinfo->invflags |= EBT_IP6_ICMP6; - if (parse_icmpv6(optarg, ipinfo->icmpv6_type, ipinfo->icmpv6_code)) + if (ebt_parse_icmp(icmpv6_codes, ARRAY_SIZE(icmpv6_codes), + optarg, ipinfo->icmpv6_type, + ipinfo->icmpv6_code)) return 0; break; @@ -493,7 +345,8 @@ static void print(const struct ebt_u_entry *entry, printf("--ip6-icmp-type "); if (ipinfo->invflags & EBT_IP6_ICMP6) printf("! "); - print_icmp_type(ipinfo->icmpv6_type, ipinfo->icmpv6_code); + ebt_print_icmp_type(icmpv6_codes, ARRAY_SIZE(icmpv6_codes), + ipinfo->icmpv6_type, ipinfo->icmpv6_code); } } -- cgit v1.2.3