summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--extensions/ebt_ip6.c165
-rw-r--r--include/ebtables_u.h17
-rw-r--r--useful_functions.c151
3 files changed, 174 insertions, 159 deletions
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 <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 35a5bcc..17afa94 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 d14cbe9..8f54bae 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");
+}