Allow using these functions for ebt_ip as well.

Signed-off-by: Matthias Schiffer <mschif...@universe-factory.net>
---
 extensions/ebt_ip6.c | 165 +++------------------------------------------------
 include/ebtables_u.h |  17 +++++-
 useful_functions.c   | 151 +++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 174 insertions(+), 159 deletions(-)

diff --git a/extensions/ebt_ip6.c b/extensions/ebt_ip6.c
index dd48547b0010..347797b4afe1 100644
--- a/extensions/ebt_ip6.c
+++ b/extensions/ebt_ip6.c
@@ -11,9 +11,6 @@
  *
  */
 
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -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);
        }
 }
 
diff --git a/include/ebtables_u.h b/include/ebtables_u.h
index 35a5bcc54c86..17afa9487f5a 100644
--- a/include/ebtables_u.h
+++ b/include/ebtables_u.h
@@ -222,6 +222,15 @@ struct ebt_u_target
        struct ebt_u_target *next;
 };
 
+
+struct ebt_icmp_names {
+       const char *name;
+       uint8_t type;
+       uint8_t code_min, code_max;
+};
+
+
+
 /* libebtc.c */
 
 extern struct ebt_u_table *ebt_tables;
@@ -300,11 +309,17 @@ void ebt_print_mac_and_mask(const unsigned char *mac, 
const unsigned char *mask)
 int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char 
*mask);
 void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk);
 char *ebt_mask_to_dotted(uint32_t mask);
-void ebt_parse_ip6_address(char *address, struct in6_addr *addr, 
+void ebt_parse_ip6_address(char *address, struct in6_addr *addr,
                                                   struct in6_addr *msk);
 char *ebt_ip6_to_numeric(const struct in6_addr *addrp);
 char *ebt_ip6_mask_to_string(const struct in6_addr *msk);
 
+int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes,
+                  const char *icmptype, uint8_t type[], uint8_t code[]);
+void ebt_print_icmp_type(const struct ebt_icmp_names *icmp_codes,
+                        size_t n_codes, uint8_t *type, uint8_t *code);
+void ebt_print_icmp_types(const struct ebt_icmp_names *icmp_codes,
+                         size_t n_codes);
 
 int do_command(int argc, char *argv[], int exec_style,
                struct ebt_u_replace *replace_);
diff --git a/useful_functions.c b/useful_functions.c
index d14cbe9dbdba..8f54bae83fae 100644
--- a/useful_functions.c
+++ b/useful_functions.c
@@ -24,6 +24,9 @@
  */
 #include "include/ebtables_u.h"
 #include "include/ethernetdb.h"
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
 #include <stdio.h>
 #include <netinet/ether.h>
 #include <string.h>
@@ -34,6 +37,7 @@
 #include <sys/socket.h>
 #include <arpa/inet.h>
 
+
 const unsigned char mac_type_unicast[ETH_ALEN] =   {0,0,0,0,0,0};
 const unsigned char msk_type_unicast[ETH_ALEN] =   {1,0,0,0,0,0};
 const unsigned char mac_type_multicast[ETH_ALEN] = {1,0,0,0,0,0};
@@ -188,7 +192,7 @@ static int undot_ip(char *ip, unsigned char *ip2)
                        return -1;
                *q = '\0';
                onebyte = strtol(p, &end, 10);
-               if (*end != '\0' || onebyte > 255 || onebyte < 0)   
+               if (*end != '\0' || onebyte > 255 || onebyte < 0)
                        return -1;
                ip2[i] = (unsigned char)onebyte;
                p = q + 1;
@@ -275,7 +279,7 @@ char *ebt_mask_to_dotted(uint32_t mask)
                *buf = '\0';
        else
                /* Mask was not a decent combination of 1's and 0's */
-               sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0], 
+               sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0],
                   ((unsigned char *)&mask)[1], ((unsigned char *)&mask)[2],
                   ((unsigned char *)&mask)[3]);
 
@@ -424,3 +428,146 @@ char *ebt_ip6_mask_to_string(const struct in6_addr *msk)
                sprintf(buf, "/%s", ebt_ip6_to_numeric(msk));
        return buf;
 }
+
+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;
+}
+
+int ebt_parse_icmp(const struct ebt_icmp_names *icmp_codes, size_t n_codes,
+                  const char *icmptype, uint8_t type[], uint8_t code[])
+{
+       unsigned int match = n_codes;
+       unsigned int i;
+       long number[2];
+
+       for (i = 0; i < n_codes; i++) {
+               if (strncasecmp(icmp_codes[i].name, icmptype, strlen(icmptype)))
+                       continue;
+               if (match != n_codes)
+                       ebt_print_error("Ambiguous ICMP type `%s':"
+                                       " `%s' or `%s'?",
+                                       icmptype, icmp_codes[match].name,
+                                       icmp_codes[i].name);
+               match = i;
+       }
+
+       if (match < n_codes) {
+               type[0] = type[1] = icmp_codes[match].type;
+               code[0] = icmp_codes[match].code_min;
+               code[1] = icmp_codes[match].code_max;
+       } else {
+               char *next = parse_range(icmptype, 0, 255, number);
+               if (!next) {
+                       ebt_print_error("Unknown ICMP type `%s'",
+                                                       icmptype);
+                       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_icmp_code(uint8_t *code)
+{
+       if (code[0] == code[1])
+               printf("/%"PRIu8 " ", code[0]);
+       else
+               printf("/%"PRIu8":%"PRIu8 " ", code[0], code[1]);
+}
+
+void ebt_print_icmp_type(const struct ebt_icmp_names *icmp_codes,
+                        size_t n_codes, 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 < n_codes; i++) {
+               if (icmp_codes[i].type != type[0])
+                       continue;
+
+               if (icmp_codes[i].code_min == code[0] &&
+                   icmp_codes[i].code_max == code[1]) {
+                       printf("%s ", icmp_codes[i].name);
+                       return;
+               }
+       }
+       printf("%"PRIu8, type[0]);
+       print_icmp_code(code);
+}
+
+void ebt_print_icmp_types(const struct ebt_icmp_names *icmp_codes,
+                         size_t n_codes)
+{
+       unsigned int i;
+
+       for (i = 0; i < n_codes; i++) {
+               if (i && icmp_codes[i].type == icmp_codes[i-1].type) {
+                       if (icmp_codes[i].code_min == icmp_codes[i-1].code_min
+                           && (icmp_codes[i].code_max
+                               == icmp_codes[i-1].code_max))
+                               printf(" (%s)", icmp_codes[i].name);
+                       else
+                               printf("\n   %s", icmp_codes[i].name);
+               }
+               else
+                       printf("\n%s", icmp_codes[i].name);
+       }
+       printf("\n");
+}
-- 
2.16.2

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to