summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart De Schuymer <bdschuym@pandora.be>2005-02-08 20:02:28 +0000
committerBart De Schuymer <bdschuym@pandora.be>2005-02-08 20:02:28 +0000
commitff587205009a0d49e2d086765de87dc619b028bb (patch)
treed1d7fd0768212c24f2adcfd9c720975394f85694
parent96ce8685fe4011ef08b0f4fe2778b523c3740766 (diff)
general cleanup + add -C and -c
-rw-r--r--ChangeLog2
-rw-r--r--communication.c3
-rw-r--r--ebtables.c71
-rw-r--r--extensions/ebt_802_3.c29
-rw-r--r--extensions/ebt_among.c75
-rw-r--r--extensions/ebt_arp.c69
-rw-r--r--extensions/ebt_arpreply.c38
-rw-r--r--extensions/ebt_inat.c8
-rw-r--r--extensions/ebt_ip.c95
-rw-r--r--extensions/ebt_limit.c58
-rw-r--r--extensions/ebt_log.c31
-rw-r--r--extensions/ebt_mark.c23
-rw-r--r--extensions/ebt_mark_m.c23
-rw-r--r--extensions/ebt_nat.c48
-rw-r--r--extensions/ebt_pkttype.c22
-rw-r--r--extensions/ebt_redirect.c19
-rw-r--r--extensions/ebt_standard.c8
-rw-r--r--extensions/ebt_stp.c34
-rw-r--r--extensions/ebt_ulog.c46
-rw-r--r--extensions/ebt_vlan.c286
-rw-r--r--extensions/ebtable_broute.c8
-rw-r--r--extensions/ebtable_filter.c8
-rw-r--r--extensions/ebtable_nat.c8
-rw-r--r--include/ebtables_u.h22
-rw-r--r--libebtc.c121
-rw-r--r--useful_functions.c70
26 files changed, 636 insertions, 589 deletions
diff --git a/ChangeLog b/ChangeLog
index af1fe66..3507924 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,8 @@
* added the ebtablesd/ebtablesu scheme to allow faster
addition of rules (and to test the modular code).
* some small fixes
+ * added -c option (initialize counters)
+ * added -C option (change counters)
20031102
Since last entry:
* <grzes_at_gnu.univ.gda.pl> added arpreply and among modules
diff --git a/communication.c b/communication.c
index f712b2b..e93217a 100644
--- a/communication.c
+++ b/communication.c
@@ -362,6 +362,7 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl, int exec_style)
old++;
/* We've set a new counter */
new++;
+ next = next->next;
} else if (cc->type == CNT_DEL) {
/* Don't use this old counter */
old++;
@@ -373,9 +374,9 @@ void ebt_deliver_counters(struct ebt_u_replace *u_repl, int exec_style)
old++;
new++;
}
+ next = next->next;
}
cc = cc->next;
- next = next->next;
}
free(u_repl->counters);
diff --git a/ebtables.c b/ebtables.c
index 8723e66..f3e8cdd 100644
--- a/ebtables.c
+++ b/ebtables.c
@@ -58,6 +58,7 @@ static struct option ebt_original_options[] =
{ "help" , no_argument , 0, 'h' },
{ "jump" , required_argument, 0, 'j' },
{ "set-counter" , required_argument, 0, 'c' },
+ { "change-counter", required_argument, 0, 'C' },
{ "proto" , required_argument, 0, 'p' },
{ "protocol" , required_argument, 0, 'p' },
{ "db" , required_argument, 0, 'b' },
@@ -442,6 +443,33 @@ static int parse_delete_rule(const char *argv, int *rule_nr, int *rule_nr_end)
return 0;
}
+static int parse_change_counters_rule(int argc, char **argv, int *rule_nr, int *rule_nr_end)
+{
+ char *buffer;
+
+ if (optind + 1 >= argc || (argv[optind][0] == '-' && (argv[optind][1] < '0' || argv[optind][1] > '9')) ||
+ (argv[optind + 1][0] == '-' && (argv[optind + 1][1] < '0' && argv[optind + 1][1] > '9')))
+ ebt_print_error2("The command -C needs at least 3 arguments");
+ if (optind + 2 < argc && (argv[optind + 2][0] != '-' || (argv[optind][1] >= '0' && argv[optind][1] <= '9'))) {
+ if (optind + 3 != argc)
+ ebt_print_error2("No extra options allowed with -C start_nr[:end_nr] pcnt bcnt");
+ if (parse_delete_rule(argv[optind], rule_nr, rule_nr_end))
+ ebt_print_error2("Something is wrong with the rule number specification '%s'", argv[optind]);
+ optind++;
+ }
+
+ new_entry->cnt.pcnt = strtoull(argv[optind], &buffer, 10);
+ if (*buffer != '\0')
+ ebt_print_error2("Packet counter '%s' invalid", argv[optind])
+ optind++;
+ new_entry->cnt.bcnt = strtoull(argv[optind], &buffer, 10);
+ if (*buffer != '\0')
+ ebt_print_error2("Packet counter '%s' invalid", argv[optind])
+
+ optind++;
+ return 0;
+}
+
static int parse_iface(char *iface, char *option)
{
char *c;
@@ -464,19 +492,6 @@ void ebt_early_init_once()
ebt_iterate_targets(merge_target);
}
-#define ebt_print_error2(format, args...) {__ebt_print_error(format, ##args); \
- return -1;}
-#define ebt_check_option2(flags,mask) \
-({ebt_check_option(flags,mask); \
- if (ebt_errormsg[0] != '\0') \
- return -1;})
-#define ebt_check_inverse2(option) \
-({int __ret = ebt_check_inverse(option); \
-if (ebt_errormsg[0] != '\0') \
- return -1; \
-if (!optarg) \
- __ebt_print_error("Option without (mandatory) argument"); \
-__ret;})
#define OPT_COMMANDS (replace->flags & OPT_COMMAND || replace->flags & OPT_ZERO)
#define OPT_COMMAND 0x01
@@ -545,11 +560,12 @@ int do_command(int argc, char *argv[], int exec_style,
/* Getopt saves the day */
while ((c = getopt_long(argc, argv,
- "-A:D:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", ebt_options, NULL)) != -1) {
+ "-A:D:C:I:N:E:X::L::Z::F::P:Vhi:o:j:c:p:s:d:t:M:", ebt_options, NULL)) != -1) {
switch (c) {
case 'A': /* Add a rule */
case 'D': /* Delete a rule */
+ case 'C': /* Change counters */
case 'P': /* Define policy */
case 'I': /* Insert a rule */
case 'N': /* Make a user defined chain */
@@ -614,8 +630,11 @@ int do_command(int argc, char *argv[], int exec_style,
if (optind != argc - 1)
ebt_print_error2("No extra options allowed with -D start_nr[:end_nr]");
if (parse_delete_rule(argv[optind], &rule_nr, &rule_nr_end))
- ebt_print_error2("Problem with the specified rule number(s)");
+ ebt_print_error2("Problem with the specified rule number(s) '%s'", argv[optind]);
optind++;
+ } else if (c == 'C') {
+ if (parse_change_counters_rule(argc, argv, &rule_nr, &rule_nr_end))
+ return -1;
} else if (c == 'I') {
if (optind >= argc || (argv[optind][0] == '-' && (argv[optind][1] < '0' || argv[optind][1] > '9')))
ebt_print_error2("No rulenr for -I specified");
@@ -996,8 +1015,11 @@ print_zero:
default:
/* Is it a target option? */
t = (struct ebt_u_target *)new_entry->t;
- if ((t->parse(c - t->option_offset, argv, argc, new_entry, &t->flags, &t->t)))
+ if ((t->parse(c - t->option_offset, argv, argc, new_entry, &t->flags, &t->t))) {
+ if (ebt_errormsg[0] != '\0')
+ return -1;
goto check_extension;
+ }
/* Is it a match_option? */
for (m = ebt_matches; m; m = m->next)
@@ -1005,6 +1027,8 @@ print_zero:
break;
if (m != NULL) {
+ if (ebt_errormsg[0] != '\0')
+ return -1;
if (m->used == 0) {
ebt_add_match(new_entry, m);
m->used = 1;
@@ -1019,6 +1043,8 @@ print_zero:
if (w == NULL)
ebt_print_error2("Unknown argument: '%s', %c, '%c'", argv[optind - 1], (char)optopt, (char)c);
+ if (ebt_errormsg[0] != '\0')
+ return -1;
if (w->used == 0) {
ebt_add_watcher(new_entry, w);
w->used = 1;
@@ -1045,7 +1071,7 @@ check_extension:
/* Do the final checks */
if (replace->command == 'A' || replace->command == 'I' ||
- replace->command == 'D') {
+ replace->command == 'D' || replace->command == 'C') {
/* This will put the hook_mask right for the chains */
ebt_check_for_loops(replace);
if (ebt_errormsg[0] != '\0')
@@ -1135,9 +1161,16 @@ check_extension:
}
/* Don't reuse the added rule */
new_entry = NULL;
- } else if (replace->command == 'D')
-delete_the_rule: /* This needs to be followed by a check on ebt_errormsg[0] */
+ } else if (replace->command == 'D') {
+delete_the_rule:
ebt_delete_rule(replace, new_entry, rule_nr, rule_nr_end);
+ if (ebt_errormsg[0] != '\0')
+ return -1;
+ } else if (replace->command == 'C') {
+ ebt_change_counters(replace, new_entry, rule_nr, rule_nr_end, &(new_entry->cnt));
+ if (ebt_errormsg[0] != '\0')
+ return -1;
+ }
/* Commands -N, -E, -X, --atomic-commit, --atomic-commit, --atomic-save,
* --init-table fall through */
diff --git a/extensions/ebt_802_3.c b/extensions/ebt_802_3.c
index e0b65ee..a43d060 100644
--- a/extensions/ebt_802_3.c
+++ b/extensions/ebt_802_3.c
@@ -1,3 +1,11 @@
+/* 802_3
+ *
+ * Author:
+ * Chris Vitale <csv@bluetail.com>
+ *
+ * May 2003
+ */
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -43,28 +51,23 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
switch (c) {
case _802_3_SAP:
- ebt_check_option(flags, _802_3_SAP);
- if (ebt_check_inverse(optarg))
+ ebt_check_option2(flags, _802_3_SAP);
+ if (ebt_check_inverse2(optarg))
info->invflags |= EBT_802_3_SAP;
-
- if (optind > argc)
- ebt_print_error("Missing 802.3-sap argument");
- i = strtoul(argv[optind - 1], &end, 16);
+ i = strtoul(optarg, &end, 16);
if (i > 255 || *end != '\0')
- ebt_print_error("Problem with specified "
+ ebt_print_error2("Problem with specified "
"sap hex value, %x",i);
info->sap = i; /* one byte, so no byte order worries */
info->bitmask |= EBT_802_3_SAP;
break;
case _802_3_TYPE:
- ebt_check_option(flags, _802_3_TYPE);
- if (ebt_check_inverse(optarg))
+ ebt_check_option2(flags, _802_3_TYPE);
+ if (ebt_check_inverse2(optarg))
info->invflags |= EBT_802_3_TYPE;
- if (optind > argc)
- ebt_print_error("Missing 802.3-type argument");
- i = strtoul(argv[optind - 1], &end, 16);
+ i = strtoul(optarg, &end, 16);
if (i > 65535 || *end != '\0') {
- ebt_print_error("Problem with the specified "
+ ebt_print_error2("Problem with the specified "
"type hex value, %x",i);
}
info->type = htons(i);
diff --git a/extensions/ebt_among.c b/extensions/ebt_among.c
index 1756e44..65ce481 100644
--- a/extensions/ebt_among.c
+++ b/extensions/ebt_among.c
@@ -1,3 +1,11 @@
+/* ebt_among
+ *
+ * Authors:
+ * Grzegorz Borowiak <grzes@gnu.univ.gda.pl>
+ *
+ * August, 2003
+ */
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -9,8 +17,6 @@
#include <linux/if_ether.h>
#include <linux/netfilter_bridge/ebt_among.h>
-#define NODEBUG
-
#define AMONG_DST '1'
#define AMONG_SRC '2'
@@ -69,6 +75,8 @@ static struct ebt_mac_wormhash *new_wormhash(int n)
struct ebt_mac_wormhash *result =
(struct ebt_mac_wormhash *) malloc(size);
+ if (!result)
+ ebt_print_memory();
memset(result, 0, size);
result->poolsize = n;
return result;
@@ -181,54 +189,53 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
for (i = 0; i < 5; i++) {
if (read_until(&pc, ":", token, 2) < 0
|| token[0] == 0) {
- ebt_print_error("MAC parse error: %.20s",
- anchor);
+ ebt_print_error("MAC parse error: %.20s", anchor);
+ return NULL;
}
mac[i] = strtol(token, &endptr, 16);
if (*endptr) {
- ebt_print_error("MAC parse error: %.20s",
- anchor);
+ ebt_print_error("MAC parse error: %.20s", anchor);
+ return NULL;
}
pc++;
}
if (read_until(&pc, "=,", token, 2) == -2 || token[0] == 0) {
ebt_print_error("MAC parse error: %.20s", anchor);
+ return NULL;
}
mac[i] = strtol(token, &endptr, 16);
if (*endptr) {
ebt_print_error("MAC parse error: %.20s", anchor);
+ return NULL;
}
if (*pc == '=') {
/* an IP follows the MAC; collect similarly to MAC */
pc++;
anchor = pc;
for (i = 0; i < 3; i++) {
- if (read_until(&pc, ".", token, 3) < 0
- || token[0] == 0) {
- ebt_print_error
- ("IP parse error: %.20s",
- anchor);
+ if (read_until(&pc, ".", token, 3) < 0 || token[0] == 0) {
+ ebt_print_error("IP parse error: %.20s", anchor);
+ return NULL;
}
ip[i] = strtol(token, &endptr, 10);
if (*endptr) {
- ebt_print_error
- ("IP parse error: %.20s",
- anchor);
+ ebt_print_error("IP parse error: %.20s", anchor);
+ return NULL;
}
pc++;
}
- if (read_until(&pc, ",", token, 3) == -2
- || token[0] == 0) {
- ebt_print_error("IP parse error: %.20s",
- anchor);
+ if (read_until(&pc, ",", token, 3) == -2 || token[0] == 0) {
+ ebt_print_error("IP parse error: %.20s", anchor);
+ return NULL;
}
ip[3] = strtol(token, &endptr, 10);
if (*endptr) {
- ebt_print_error("IP parse error: %.20s",
- anchor);
+ ebt_print_error("IP parse error: %.20s", anchor);
+ return NULL;
}
if (*(uint32_t*)ip == 0) {
ebt_print_error("Illegal IP 0.0.0.0");
+ return NULL;
}
} else {
/* no IP, we set it to 0.0.0.0 */
@@ -260,6 +267,7 @@ static struct ebt_mac_wormhash *create_wormhash(const char *arg)
/* but first assert :-> */
if (*pc != ',') {
ebt_print_error("Something went wrong; no comma...\n");
+ return NULL;
}
pc++;
@@ -295,30 +303,33 @@ static int parse(int c, char **argv, int argc,
switch (c) {
case AMONG_DST:
case AMONG_SRC:
- if (ebt_check_inverse(optarg)) {
+ if (c == AMONG_DST) {
+ ebt_check_option2(flags, OPT_DST);
+ } else {
+ ebt_check_option2(flags, OPT_SRC);
+ }
+ if (ebt_check_inverse2(optarg)) {
if (c == AMONG_DST)
info->bitmask |= EBT_AMONG_DST_NEG;
else
info->bitmask |= EBT_AMONG_SRC_NEG;
}
- if (optind > argc)
- ebt_print_error("No MAC list specified\n");
- wh = create_wormhash(argv[optind - 1]);
- old_size = sizeof(struct ebt_entry_match) +
- (**match).match_size;
- h = malloc((new_size =
- old_size + ebt_mac_wormhash_size(wh)));
+ wh = create_wormhash(optarg);
+ if (ebt_errormsg[0] != '\0')
+ break;
+
+ old_size = sizeof(struct ebt_entry_match) + (**match).match_size;
+ h = malloc((new_size = old_size + ebt_mac_wormhash_size(wh)));
+ if (!h)
+ ebt_print_memory();
memcpy(h, *match, old_size);
- memcpy((char *) h + old_size, wh,
- ebt_mac_wormhash_size(wh));
+ memcpy((char *) h + old_size, wh, ebt_mac_wormhash_size(wh));
h->match_size = new_size - sizeof(struct ebt_entry_match);
info = (struct ebt_among_info *) h->data;
if (c == AMONG_DST) {
- ebt_check_option(flags, OPT_DST);
info->wh_dst_ofs =
old_size - sizeof(struct ebt_entry_match);
} else {
- ebt_check_option(flags, OPT_SRC);
info->wh_src_ofs =
old_size - sizeof(struct ebt_entry_match);
}
diff --git a/extensions/ebt_arp.c b/extensions/ebt_arp.c
index c38eec6..9eed645 100644
--- a/extensions/ebt_arp.c
+++ b/extensions/ebt_arp.c
@@ -1,3 +1,12 @@
+/* ebt_arp
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ * Tim Gardner <timg@tpi.com>
+ *
+ * April, 2002
+ */
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -92,20 +101,16 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
switch (c) {
case ARP_OPCODE:
- ebt_check_option(flags, OPT_OPCODE);
- if (ebt_check_inverse(optarg))
+ ebt_check_option2(flags, OPT_OPCODE);
+ if (ebt_check_inverse2(optarg))
arpinfo->invflags |= EBT_ARP_OPCODE;
-
- if (optind > argc)
- ebt_print_error("Missing ARP opcode argument");
- i = strtol(argv[optind - 1], &end, 10);
+ i = strtol(optarg, &end, 10);
if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
for (i = 0; i < NUMOPCODES; i++)
if (!strcasecmp(opcodes[i], optarg))
break;
if (i == NUMOPCODES)
- ebt_print_error("Problem with specified "
- "ARP opcode");
+ ebt_print_error2("Problem with specified ARP opcode");
i++;
}
arpinfo->opcode = htons(i);
@@ -113,19 +118,15 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
break;
case ARP_HTYPE:
- ebt_check_option(flags, OPT_HTYPE);
- if (ebt_check_inverse(optarg))
+ ebt_check_option2(flags, OPT_HTYPE);
+ if (ebt_check_inverse2(optarg))
arpinfo->invflags |= EBT_ARP_HTYPE;
-
- if (optind > argc)
- ebt_print_error("Missing ARP hardware type argument");
- i = strtol(argv[optind - 1], &end, 10);
+ i = strtol(optarg, &end, 10);
if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
if (!strcasecmp("Ethernet", argv[optind - 1]))
i = 1;
else
- ebt_print_error("Problem with specified ARP "
- "hardware type");
+ ebt_print_error2("Problem with specified ARP hardware type");
}
arpinfo->htype = htons(i);
arpinfo->bitmask |= EBT_ARP_HTYPE;
@@ -135,19 +136,17 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
{
uint16_t proto;
- ebt_check_option(flags, OPT_PTYPE);
- if (ebt_check_inverse(optarg))
+ ebt_check_option2(flags, OPT_PTYPE);
+ if (ebt_check_inverse2(optarg))
arpinfo->invflags |= EBT_ARP_PTYPE;
- if (optind > argc)
- ebt_print_error("Missing ARP protocol type argument");
- i = strtol(argv[optind - 1], &end, 16);
+ i = strtol(optarg, &end, 16);
if (i < 0 || i >= (0x1 << 16) || *end !='\0') {
struct ethertypeent *ent;
ent = getethertypebyname(argv[optind - 1]);
if (!ent)
- ebt_print_error("Problem with specified ARP "
+ ebt_print_error2("Problem with specified ARP "
"protocol type");
proto = ent->e_ethertype;
@@ -161,51 +160,46 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
case ARP_IP_S:
case ARP_IP_D:
if (c == ARP_IP_S) {
- ebt_check_option(flags, OPT_IP_S);
+ ebt_check_option2(flags, OPT_IP_S);
addr = &arpinfo->saddr;
mask = &arpinfo->smsk;
arpinfo->bitmask |= EBT_ARP_SRC_IP;
} else {
- ebt_check_option(flags, OPT_IP_D);
+ ebt_check_option2(flags, OPT_IP_D);
addr = &arpinfo->daddr;
mask = &arpinfo->dmsk;
arpinfo->bitmask |= EBT_ARP_DST_IP;
}
- if (ebt_check_inverse(optarg)) {
+ if (ebt_check_inverse2(optarg)) {
if (c == ARP_IP_S)
arpinfo->invflags |= EBT_ARP_SRC_IP;
else
arpinfo->invflags |= EBT_ARP_DST_IP;
}
- if (optind > argc)
- ebt_print_error("Missing ARP IP address argument");
- ebt_parse_ip_address(argv[optind - 1], addr, mask);
+ ebt_parse_ip_address(optarg, addr, mask);
break;
case ARP_MAC_S:
case ARP_MAC_D:
if (c == ARP_MAC_S) {
- ebt_check_option(flags, OPT_MAC_S);
+ ebt_check_option2(flags, OPT_MAC_S);
maddr = arpinfo->smaddr;
mmask = arpinfo->smmsk;
arpinfo->bitmask |= EBT_ARP_SRC_MAC;
} else {
- ebt_check_option(flags, OPT_MAC_D);
+ ebt_check_option2(flags, OPT_MAC_D);
maddr = arpinfo->dmaddr;
mmask = arpinfo->dmmsk;
arpinfo->bitmask |= EBT_ARP_DST_MAC;
}
- if (ebt_check_inverse(optarg)) {
+ if (ebt_check_inverse2(optarg)) {
if (c == ARP_MAC_S)
arpinfo->invflags |= EBT_ARP_SRC_MAC;
else
arpinfo->invflags |= EBT_ARP_DST_MAC;
}
- if (optind > argc)
- ebt_print_error("Missing ARP MAC address argument");
- if (ebt_get_mac_and_mask(argv[optind - 1], maddr, mmask))
- ebt_print_error("Problem with ARP MAC address "
- "argument");
+ if (ebt_get_mac_and_mask(optarg, maddr, mmask))
+ ebt_print_error2("Problem with ARP MAC address argument");
break;
default:
@@ -220,8 +214,7 @@ static void final_check(const struct ebt_u_entry *entry,
{
if ((entry->ethproto != ETH_P_ARP && entry->ethproto != ETH_P_RARP) ||
entry->invflags & EBT_IPROTO)
- ebt_print_error("For (R)ARP filtering the protocol must be "
- "specified as ARP or RARP");
+ ebt_print_error("For (R)ARP filtering the protocol must be specified as ARP or RARP");
}
static void print(const struct ebt_u_entry *entry,
diff --git a/extensions/ebt_arpreply.c b/extensions/ebt_arpreply.c
index 9c50519..32e50b4 100644
--- a/extensions/ebt_arpreply.c
+++ b/extensions/ebt_arpreply.c
@@ -1,3 +1,12 @@
+/* ebt_arpreply
+ *
+ * Authors:
+ * Grzegorz Borowiak <grzes@gnu.univ.gda.pl>
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * August, 2003
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -48,17 +57,16 @@ static int parse(int c, char **argv, int argc,
switch (c) {
case REPLY_MAC:
- ebt_check_option(flags, OPT_REPLY_MAC);
+ ebt_check_option2(flags, OPT_REPLY_MAC);
if (!(addr = ether_aton(optarg)))
- ebt_print_error("Problem with specified "
- "--arpreply-mac mac");
+ ebt_print_error2("Problem with specified --arpreply-mac mac");
memcpy(replyinfo->mac, addr, ETH_ALEN);
mac_supplied = 1;
break;
case REPLY_TARGET:
- ebt_check_option(flags, OPT_REPLY_TARGET);
+ ebt_check_option2(flags, OPT_REPLY_TARGET);
if (FILL_TARGET(optarg, replyinfo->target))
- ebt_print_error("Illegal --arpreply-target target");
+ ebt_print_error2("Illegal --arpreply-target target");
break;
default:
@@ -74,17 +82,17 @@ static void final_check(const struct ebt_u_entry *entry,
struct ebt_arpreply_info *replyinfo =
(struct ebt_arpreply_info *)target->data;
- if (entry->ethproto != ETH_P_ARP || entry->invflags & EBT_IPROTO)
- ebt_print_error("For ARP replying the protocol must be "
- "specified as ARP");
- if (time == 0 && mac_supplied == 0)
+ if (entry->ethproto != ETH_P_ARP || entry->invflags & EBT_IPROTO) {
+ ebt_print_error("For ARP replying the protocol must be specified as ARP");
+ } else if (time == 0 && mac_supplied == 0) {
ebt_print_error("No arpreply mac supplied");
- if (BASE_CHAIN && replyinfo->target == EBT_RETURN)
- ebt_print_error("--arpreply-target RETURN not allowed on "
- "base chain");
- CLEAR_BASE_CHAIN_BIT;
- if (strcmp(name, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING))
- ebt_print_error("arpreply only allowed in PREROUTING");
+ } else if (BASE_CHAIN && replyinfo->target == EBT_RETURN) {
+ ebt_print_error("--arpreply-target RETURN not allowed on base chain");
+ } else {
+ CLEAR_BASE_CHAIN_BIT;
+ if (strcmp(name, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING))
+ ebt_print_error("arpreply only allowed in PREROUTING");
+ }
}
static void print(const struct ebt_u_entry *entry,
diff --git a/extensions/ebt_inat.c b/extensions/ebt_inat.c
index aae5cab..1aa9435 100644
--- a/extensions/ebt_inat.c
+++ b/extensions/ebt_inat.c
@@ -1,3 +1,11 @@
+/* ebt_inat
+ *
+ * Authors:
+ * Grzegorz Borowiak <grzes@gnu.univ.gda.pl>
+ *
+ * August, 2003
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/extensions/ebt_ip.c b/extensions/ebt_ip.c
index c81e687..8e45171 100644
--- a/extensions/ebt_ip.c
+++ b/extensions/ebt_ip.c
@@ -1,29 +1,13 @@
-/*
- * ebtables ebt_ip: IP extension module for userspace
+/* ebt_ip
*
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
*
- * Changes:
+ * Changes:
* added ip-sport and ip-dport; parsing of port arguments is
* based on code from iptables-1.2.7a
* Innominate Security Technologies AG <mhopf@innominate.com>
* September, 2002
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
*/
#include <stdio.h>
@@ -76,7 +60,7 @@ static uint16_t parse_port(const char *protocol, const char *name)
}
ebt_print_error("Problem with specified %s port '%s'",
protocol?protocol:"", name);
- return 0; /* never reached */
+ return 0;
}
static void
@@ -92,7 +76,11 @@ parse_port_range(const char *protocol, const char *portstring, uint16_t *ports)
*cp = '\0';
cp++;
ports[0] = buffer[0] ? parse_port(protocol, buffer) : 0;
+ if (ebt_errormsg[0] != '\0')
+ return;
ports[1] = cp[0] ? parse_port(protocol, cp) : 0xFFFF;
+ if (ebt_errormsg[0] != '\0')
+ return;
if (ports[0] > ports[1])
ebt_print_error("Invalid portrange (min > max)");
@@ -143,81 +131,67 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
switch (c) {
case IP_SOURCE:
- ebt_check_option(flags, OPT_SOURCE);
+ ebt_check_option2(flags, OPT_SOURCE);
ipinfo->bitmask |= EBT_IP_SOURCE;
case IP_DEST:
if (c == IP_DEST) {
- ebt_check_option(flags, OPT_DEST);
+ ebt_check_option2(flags, OPT_DEST);
ipinfo->bitmask |= EBT_IP_DEST;
}
- if (ebt_check_inverse(optarg)) {
+ if (ebt_check_inverse2(optarg)) {
if (c == IP_SOURCE)
ipinfo->invflags |= EBT_IP_SOURCE;
else
ipinfo->invflags |= EBT_IP_DEST;
}
-
- if (optind > argc)
- ebt_print_error("Missing IP address argument");
if (c == IP_SOURCE)
- ebt_parse_ip_address(argv[optind - 1], &ipinfo->saddr,
- &ipinfo->smsk);
+ ebt_parse_ip_address(optarg, &ipinfo->saddr, &ipinfo->smsk);
else
- ebt_parse_ip_address(argv[optind - 1], &ipinfo->daddr,
- &ipinfo->dmsk);
+ ebt_parse_ip_address(optarg, &ipinfo->daddr, &ipinfo->dmsk);
break;
case IP_SPORT:
case IP_DPORT:
if (c == IP_SPORT) {
- ebt_check_option(flags, OPT_SPORT);
+ ebt_check_option2(flags, OPT_SPORT);
ipinfo->bitmask |= EBT_IP_SPORT;
- if (ebt_check_inverse(optarg))
+ if (ebt_check_inverse2(optarg))
ipinfo->invflags |= EBT_IP_SPORT;
} else {
- ebt_check_option(flags, OPT_DPORT);
+ ebt_check_option2(flags, OPT_DPORT);
ipinfo->bitmask |= EBT_IP_DPORT;
- if (ebt_check_inverse(optarg))
+ if (ebt_check_inverse2(optarg))
ipinfo->invflags |= EBT_IP_DPORT;
}
- if (optind > argc)
- ebt_print_error("Missing port argument");
if (c == IP_SPORT)
- parse_port_range(NULL, argv[optind - 1], ipinfo->sport);
+ parse_port_range(NULL, optarg, ipinfo->sport);
else
- parse_port_range(NULL, argv[optind - 1], ipinfo->dport);
+ parse_port_range(NULL, optarg, ipinfo->dport);
break;
case IP_myTOS:
- ebt_check_option(flags, OPT_TOS);
- if (ebt_check_inverse(optarg))
+ ebt_check_option2(flags, OPT_TOS);
+ if (ebt_check_inverse2(optarg))
ipinfo->invflags |= EBT_IP_TOS;
-
- if (optind > argc)
- ebt_print_error("Missing IP tos argument");
- i = strtol(argv[optind - 1], &end, 16);
+ i = strtol(optarg, &end, 16);
if (i < 0 || i > 255 || *end != '\0')
- ebt_print_error("Problem with specified IP tos");
+ ebt_print_error2("Problem with specified IP tos");
ipinfo->tos = i;
ipinfo->bitmask |= EBT_IP_TOS;
break;
case IP_PROTO:
- ebt_check_option(flags, OPT_PROTO);
- if (ebt_check_inverse(optarg))
+ ebt_check_option2(flags, OPT_PROTO);
+ if (ebt_check_inverse2(optarg))
ipinfo->invflags |= EBT_IP_PROTO;
- if (optind > argc)
- ebt_print_error("Missing IP protocol argument");
- i = strtoul(argv[optind - 1], &end, 10);
+ i = strtoul(optarg, &end, 10);
if (*end != '\0') {
struct protoent *pe;
- pe = getprotobyname(argv[optind - 1]);
+ pe = getprotobyname(optarg);
if (pe == NULL)
- ebt_print_error
- ("Unknown specified IP protocol - %s",
- argv[optind - 1]);
+ ebt_print_error("Unknown specified IP protocol - %s", argv[optind - 1]);
ipinfo->protocol = pe->p_proto;
} else {
ipinfo->protocol = (unsigned char) i;
@@ -236,11 +210,10 @@ static void final_check(const struct ebt_u_entry *entry,
{
struct ebt_ip_info *ipinfo = (struct ebt_ip_info *)match->data;
- if (entry->ethproto != ETH_P_IP || entry->invflags & EBT_IPROTO)
+ if (entry->ethproto != ETH_P_IP || entry->invflags & EBT_IPROTO) {
ebt_print_error("For IP filtering the protocol must be "
"specified as IPv4");
-
- if (ipinfo->bitmask & (EBT_IP_SPORT|EBT_IP_DPORT) &&
+ } else if (ipinfo->bitmask & (EBT_IP_SPORT|EBT_IP_DPORT) &&
(!(ipinfo->bitmask & EBT_IP_PROTO) ||
ipinfo->invflags & EBT_IP_PROTO ||
(ipinfo->protocol!=IPPROTO_TCP &&
@@ -294,16 +267,14 @@ static void print(const struct ebt_u_entry *entry,
}
if (ipinfo->bitmask & EBT_IP_SPORT) {
printf("--ip-sport ");
- if (ipinfo->invflags & EBT_IP_SPORT) {
+ if (ipinfo->invflags & EBT_IP_SPORT)
printf("! ");
- }
print_port_range(ipinfo->sport);
}
if (ipinfo->bitmask & EBT_IP_DPORT) {
printf("--ip-dport ");
- if (ipinfo->invflags & EBT_IP_DPORT) {
+ if (ipinfo->invflags & EBT_IP_DPORT)
printf("! ");
- }
print_port_range(ipinfo->dport);
}
}
diff --git a/extensions/ebt_limit.c b/extensions/ebt_limit.c
index 6dcd50d..5655b59 100644
--- a/extensions/ebt_limit.c
+++ b/extensions/ebt_limit.c
@@ -1,32 +1,33 @@
-/* Shared library add-on to ebtables to add limit support.
+/* ebt_limit
*
- * Swipted from iptables' limit match.
+ * Authors:
+ * Tom Marshall <tommy@home.tig-grr.com>
+ *
+ * Mostly copied from iptables' limit match.
+ *
+ * September, 2003
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
+#include <errno.h>
#include "../include/ebtables_u.h"
#include <linux/netfilter_bridge/ebt_limit.h>
#define EBT_LIMIT_AVG "3/hour"
#define EBT_LIMIT_BURST 5
-/* from iptables.c */
-#include <errno.h>
-int
-string_to_number(const char *s, unsigned int min, unsigned int max,
- unsigned int *ret)
+int string_to_number(const char *s, unsigned int min, unsigned int max,
+ unsigned int *ret)
{
long number;
char *end;
- /* Handle hex, octal, etc. */
errno = 0;
number = strtol(s, &end, 0);
if (*end == '\0' && end != s) {
- /* we parsed a number, let's see if we want this */
if (errno != ERANGE && min <= number && number <= max) {
*ret = number;
return 0;
@@ -37,7 +38,6 @@ string_to_number(const char *s, unsigned int min, unsigned int max,
#define FLAG_LIMIT 0x01
#define FLAG_LIMIT_BURST 0x02
-
#define ARG_LIMIT '1'
#define ARG_LIMIT_BURST '2'
@@ -52,12 +52,11 @@ static void print_help(void)
{
printf(
"limit options:\n"
-"--limit avg max average match rate: default "EBT_LIMIT_AVG"\n"
+"--limit avg : max average match rate: default "EBT_LIMIT_AVG"\n"
" [Packets per second unless followed by \n"
" /sec /minute /hour /day postfixes]\n"
-"--limit-burst number number to match in a burst, -1 < number < 10001,\n"
-" default %u\n"
-"\n", EBT_LIMIT_BURST);
+"--limit-burst number : number to match in a burst, -1 < number < 10001,\n"
+" default %u\n", EBT_LIMIT_BURST);
}
static int parse_rate(const char *rate, u_int32_t *val)
@@ -120,20 +119,19 @@ static int parse(int c, char **argv, int argc,
switch(c) {
case ARG_LIMIT:
- ebt_check_option(flags, FLAG_LIMIT);
- if (ebt_check_inverse(optarg))
- ebt_print_error("Unexpected `!' after --limit");
+ ebt_check_option2(flags, FLAG_LIMIT);
+ if (ebt_check_inverse2(optarg))
+ ebt_print_error2("Unexpected `!' after --limit");
if (!parse_rate(optarg, &r->avg))
- ebt_print_error("bad rate `%s'", optarg);
+ ebt_print_error2("bad rate `%s'", optarg);
break;
case ARG_LIMIT_BURST:
- ebt_check_option(flags, FLAG_LIMIT_BURST);
- if (ebt_check_inverse(optarg))
- ebt_print_error("Unexpected `!' after --limit-burst");
-
+ ebt_check_option2(flags, FLAG_LIMIT_BURST);
+ if (ebt_check_inverse2(optarg))
+ ebt_print_error2("Unexpected `!' after --limit-burst");
if (string_to_number(optarg, 0, 10000, &num) == -1)
- ebt_print_error("bad --limit-burst `%s'", optarg);
+ ebt_print_error2("bad --limit-burst `%s'", optarg);
r->burst = num;
break;
@@ -148,7 +146,6 @@ static void final_check(const struct ebt_u_entry *entry,
const struct ebt_entry_match *match, const char *name,
unsigned int hookmask, unsigned int time)
{
- /* empty */
}
struct rates
@@ -177,17 +174,18 @@ static void print_rate(u_int32_t period)
printf("%u/%s ", g_rates[i-1].mult / period, g_rates[i-1].name);
}
-/* Prints out the matchinfo. */
-static void
-print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match)
+static void print(const struct ebt_u_entry *entry,
+ const struct ebt_entry_match *match)
{
struct ebt_limit_info *r = (struct ebt_limit_info *)match->data;
- printf("limit: avg "); print_rate(r->avg);
- printf("burst %u ", r->burst);
+ printf("--limit ");
+ print_rate(r->avg);
+ printf("--limit-burst %u ", r->burst);
}
-static int compare(const struct ebt_entry_match* m1, const struct ebt_entry_match *m2)
+static int compare(const struct ebt_entry_match* m1,
+ const struct ebt_entry_match *m2)
{
struct ebt_limit_info* li1 = (struct ebt_limit_info*)m1->data;
struct ebt_limit_info* li2 = (struct ebt_limit_info*)m2->data;
diff --git a/extensions/ebt_log.c b/extensions/ebt_log.c
index f455f9f..07a5fe9 100644
--- a/extensions/ebt_log.c
+++ b/extensions/ebt_log.c
@@ -1,3 +1,11 @@
+/* ebt_log
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * April, 2002
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -103,35 +111,43 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
switch (c) {
case LOG_PREFIX:
- ebt_check_option(flags, OPT_PREFIX);
+ ebt_check_option2(flags, OPT_PREFIX);
+ if (ebt_check_inverse(optarg))
+ ebt_print_error2("Unexpected `!' after --log-prefix");
if (strlen(optarg) > sizeof(loginfo->prefix) - 1)
- ebt_print_error("Prefix too long");
+ ebt_print_error2("Prefix too long");
strcpy(loginfo->prefix, optarg);
break;
case LOG_LEVEL:
- ebt_check_option(flags, OPT_LEVEL);
+ ebt_check_option2(flags, OPT_LEVEL);
i = strtol(optarg, &end, 16);
if (*end != '\0' || i < 0 || i > 7)
loginfo->loglevel = name_to_loglevel(optarg);
else
loginfo->loglevel = i;
if (loginfo->loglevel == 9)
- ebt_print_error("Problem with the log-level");
+ ebt_print_error2("Problem with the log-level");
break;
case LOG_IP:
- ebt_check_option(flags, OPT_IP);
+ ebt_check_option2(flags, OPT_IP);
+ if (ebt_check_inverse(optarg))
+ ebt_print_error2("Unexpected `!' after --log-ip");
loginfo->bitmask |= EBT_LOG_IP;
break;
case LOG_ARP:
- ebt_check_option(flags, OPT_ARP);
+ ebt_check_option2(flags, OPT_ARP);
+ if (ebt_check_inverse(optarg))
+ ebt_print_error2("Unexpected `!' after --log-arp");
loginfo->bitmask |= EBT_LOG_ARP;
break;
case LOG_LOG:
- ebt_check_option(flags, OPT_LOG);
+ ebt_check_option2(flags, OPT_LOG);
+ if (ebt_check_inverse(optarg))
+ ebt_print_error2("Unexpected `!' after --log");
break;
default:
return 0;
@@ -143,7 +159,6 @@ static void final_check(const struct ebt_u_entry *entry,
const struct ebt_entry_watcher *watcher, const char *name,
unsigned int hookmask, unsigned int time)
{
- return;
}
static void print(const struct ebt_u_entry *entry,
diff --git a/extensions/ebt_mark.c b/extensions/ebt_mark.c
index 11bcc12..c7c79aa 100644
--- a/extensions/ebt_mark.c
+++ b/extensions/ebt_mark.c
@@ -1,3 +1,11 @@
+/* ebt_mark
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * July, 2002
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -49,15 +57,15 @@ static int parse(int c, char **argv, int argc,
switch (c) {
case MARK_TARGET:
- ebt_check_option(flags, OPT_MARK_TARGET);
+ ebt_check_option2(flags, OPT_MARK_TARGET);
if (FILL_TARGET(optarg, markinfo->target))
- ebt_print_error("Illegal --mark-target target");
+ ebt_print_error2("Illegal --mark-target target");
break;
case MARK_SETMARK:
- ebt_check_option(flags, OPT_MARK_SETMARK);
+ ebt_check_option2(flags, OPT_MARK_SETMARK);
markinfo->mark = strtoul(optarg, &end, 0);
if (*end != '\0' || end == optarg)
- ebt_print_error("Bad MARK value '%s'", optarg);
+ ebt_print_error2("Bad MARK value '%s'", optarg);
mark_supplied = 1;
break;
default:
@@ -73,11 +81,10 @@ static void final_check(const struct ebt_u_entry *entry,
struct ebt_mark_t_info *markinfo =
(struct ebt_mark_t_info *)target->data;
- if (time == 0 && mark_supplied == 0)
+ if (time == 0 && mark_supplied == 0) {
ebt_print_error("No mark value supplied");
- if (BASE_CHAIN && markinfo->target == EBT_RETURN)
- ebt_print_error("--mark-target RETURN not allowed on base "
- "chain");
+ } else if (BASE_CHAIN && markinfo->target == EBT_RETURN)
+ ebt_print_error("--mark-target RETURN not allowed on base chain");
}
static void print(const struct ebt_u_entry *entry,
diff --git a/extensions/ebt_mark_m.c b/extensions/ebt_mark_m.c
index 2cc371a..8c5913e 100644
--- a/extensions/ebt_mark_m.c
+++ b/extensions/ebt_mark_m.c
@@ -1,3 +1,11 @@
+/* ebt_mark_m
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * July, 2002
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -40,22 +48,19 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
switch (c) {
case MARK:
- ebt_check_option(flags, MARK);
- if (ebt_check_inverse(optarg))
+ ebt_check_option2(flags, MARK);
+ if (ebt_check_inverse2(optarg))
markinfo->invert = 1;
- if (optind > argc)
- ebt_print_error("No mark specified");
- markinfo->mark = strtoul(argv[optind - 1], &end, 0);
+ markinfo->mark = strtoul(optarg, &end, 0);
markinfo->bitmask = EBT_MARK_AND;
if (*end == '/') {
- if (end == argv[optind - 1])
+ if (end == optarg)
markinfo->bitmask = EBT_MARK_OR;
markinfo->mask = strtoul(end+1, &end, 0);
} else
markinfo->mask = 0xffffffff;
- if ( *end != '\0' || end == argv[optind - 1])
- ebt_print_error("Bad mark value '%s'",
- argv[optind - 1]);
+ if ( *end != '\0' || end == optarg)
+ ebt_print_error2("Bad mark value '%s'", optarg);
break;
default:
return 0;
diff --git a/extensions/ebt_nat.c b/extensions/ebt_nat.c
index f2e79ca..5906ac4 100644
--- a/extensions/ebt_nat.c
+++ b/extensions/ebt_nat.c
@@ -1,3 +1,11 @@
+/* ebt_nat
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * June, 2002
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -73,17 +81,16 @@ static int parse_s(int c, char **argv, int argc,
switch (c) {
case NAT_S:
- ebt_check_option(flags, OPT_SNAT);
+ ebt_check_option2(flags, OPT_SNAT);
to_source_supplied = 1;
if (!(addr = ether_aton(optarg)))
- ebt_print_error("Problem with specified --to-source "
- "mac");
+ ebt_print_error2("Problem with specified --to-source mac");
memcpy(natinfo->mac, addr, ETH_ALEN);
break;
case NAT_S_TARGET:
- ebt_check_option(flags, OPT_SNAT_TARGET);
+ ebt_check_option2(flags, OPT_SNAT_TARGET);
if (FILL_TARGET(optarg, natinfo->target))
- ebt_print_error("Illegal --snat-target target");
+ ebt_print_error2("Illegal --snat-target target");
break;
default:
return 0;
@@ -102,17 +109,16 @@ static int parse_d(int c, char **argv, int argc,
switch (c) {
case NAT_D:
- ebt_check_option(flags, OPT_DNAT);
+ ebt_check_option2(flags, OPT_DNAT);
to_dest_supplied = 1;
if (!(addr = ether_aton(optarg)))
- ebt_print_error("Problem with specified "
- "--to-destination mac");
+ ebt_print_error2("Problem with specified --to-destination mac");
memcpy(natinfo->mac, addr, ETH_ALEN);
break;
case NAT_D_TARGET:
- ebt_check_option(flags, OPT_DNAT_TARGET);
+ ebt_check_option2(flags, OPT_DNAT_TARGET);
if (FILL_TARGET(optarg, natinfo->target))
- ebt_print_error("Illegal --dnat-target target");
+ ebt_print_error2("Illegal --dnat-target target");
break;
default:
return 0;
@@ -126,13 +132,14 @@ static void final_check_s(const struct ebt_u_entry *entry,
{
struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
- if (BASE_CHAIN && natinfo->target == EBT_RETURN)
- ebt_print_error("--snat-target RETURN not allowed on base "
- "chain");
+ if (BASE_CHAIN && natinfo->target == EBT_RETURN) {
+ ebt_print_error("--snat-target RETURN not allowed on base chain");
+ return;
+ }
CLEAR_BASE_CHAIN_BIT;
- if ((hookmask & ~(1 << NF_BR_POST_ROUTING)) || strcmp(name, "nat"))
+ if ((hookmask & ~(1 << NF_BR_POST_ROUTING)) || strcmp(name, "nat")) {
ebt_print_error("Wrong chain for snat");
- if (time == 0 && to_source_supplied == 0)
+ } else if (time == 0 && to_source_supplied == 0)
ebt_print_error("No snat address supplied");
}
@@ -142,15 +149,16 @@ static void final_check_d(const struct ebt_u_entry *entry,
{
struct ebt_nat_info *natinfo = (struct ebt_nat_info *)target->data;
- if (BASE_CHAIN && natinfo->target == EBT_RETURN)
- ebt_print_error("--dnat-target RETURN not allowed on base "
- "chain");
+ if (BASE_CHAIN && natinfo->target == EBT_RETURN) {
+ ebt_print_error("--dnat-target RETURN not allowed on base chain");
+ return;
+ }
CLEAR_BASE_CHAIN_BIT;
if (((hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))
|| strcmp(name, "nat")) &&
- ((hookmask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute")))
+ ((hookmask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute"))) {
ebt_print_error("Wrong chain for dnat");
- if (time == 0 && to_dest_supplied == 0)
+ } if (time == 0 && to_dest_supplied == 0)
ebt_print_error("No dnat address supplied");
}
diff --git a/extensions/ebt_pkttype.c b/extensions/ebt_pkttype.c
index f7893bb..7894d0d 100644
--- a/extensions/ebt_pkttype.c
+++ b/extensions/ebt_pkttype.c
@@ -1,9 +1,9 @@
-/*
- * ebtables ebt_pkttype
+/* ebt_pkttype
*
- * Authors:
- * Bart De Schuymer <bdschuym@pandora.be>
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
*
+ * April, 2003
*/
#include <stdio.h>
@@ -38,7 +38,7 @@ static void print_help()
printf(
"pkttype options:\n"
"--pkttype-type [!] type: class the packet belongs to\n"
-"Possible values: broadcast, multicast, host, otherhost any byte value.\n");
+"Possible values: broadcast, multicast, host, otherhost, or any other byte value (which would be pretty useless).\n");
}
static void init(struct ebt_entry_match *match)
@@ -58,25 +58,21 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
switch (c) {
case '1':
ebt_check_option(flags, 1);
- if (ebt_check_inverse(optarg))
+ if (ebt_check_inverse2(optarg))
ptinfo->invert = 1;
- if (optind > argc)
- ebt_print_error("Missing pkttype class specification");
-
- i = strtol(argv[optind - 1], &end, 16);
+ i = strtol(optarg, &end, 16);
if (*end != '\0') {
int j = 0;
i = -1;
while (classes[j][0])
- if (!strcasecmp(argv[optind - 1], classes[j++])) {
+ if (!strcasecmp(optarg, classes[j++])) {
i = j - 1;
break;
}
}
if (i < 0 || i > 255)
- ebt_print_error("Problem with specified pkttype class");
+ ebt_print_error2("Problem with specified pkttype class");
ptinfo->pkt_type = (uint8_t)i;
-
break;
default:
return 0;
diff --git a/extensions/ebt_redirect.c b/extensions/ebt_redirect.c
index ba7f6b1..8630254 100644
--- a/extensions/ebt_redirect.c
+++ b/extensions/ebt_redirect.c
@@ -1,3 +1,11 @@
+/* ebt_redirect
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * April, 2002
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -38,9 +46,9 @@ static int parse(int c, char **argv, int argc,
switch (c) {
case REDIRECT_TARGET:
- ebt_check_option(flags, OPT_REDIRECT_TARGET);
+ ebt_check_option2(flags, OPT_REDIRECT_TARGET);
if (FILL_TARGET(optarg, redirectinfo->target))
- ebt_print_error("Illegal --redirect-target target");
+ ebt_print_error2("Illegal --redirect-target target");
break;
default:
return 0;
@@ -55,9 +63,10 @@ static void final_check(const struct ebt_u_entry *entry,
struct ebt_redirect_info *redirectinfo =
(struct ebt_redirect_info *)target->data;
- if (BASE_CHAIN && redirectinfo->target == EBT_RETURN)
- ebt_print_error("--redirect-target RETURN not allowed on "
- "base chain");
+ if (BASE_CHAIN && redirectinfo->target == EBT_RETURN) {
+ ebt_print_error("--redirect-target RETURN not allowed on base chain");
+ return;
+ }
CLEAR_BASE_CHAIN_BIT;
if ( ((hookmask & ~(1 << NF_BR_PRE_ROUTING)) || strcmp(name, "nat")) &&
((hookmask & ~(1 << NF_BR_BROUTING)) || strcmp(name, "broute")) )
diff --git a/extensions/ebt_standard.c b/extensions/ebt_standard.c
index 4ac3dc0..1420d1d 100644
--- a/extensions/ebt_standard.c
+++ b/extensions/ebt_standard.c
@@ -1,3 +1,11 @@
+/* ebt_standard
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * April, 2002
+ */
+
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
diff --git a/extensions/ebt_stp.c b/extensions/ebt_stp.c
index 8ed4c47..307131f 100644
--- a/extensions/ebt_stp.c
+++ b/extensions/ebt_stp.c
@@ -1,3 +1,11 @@
+/* ebt_stp
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * July, 2003
+ */
+
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@@ -157,38 +165,32 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
if (c < 'a' || c > ('a' + STP_NUMOPS - 1))
return 0;
flag = 1 << (c - 'a');
- ebt_check_option(flags, flag);
- if (ebt_check_inverse(optarg))
+ ebt_check_option2(flags, flag);
+ if (ebt_check_inverse2(optarg))
stpinfo->invflags |= flag;
- if (optind > argc)
- ebt_print_error("Missing argument for --%s", opts[c-'a'].name);
stpinfo->bitmask |= flag;
switch (flag) {
case EBT_STP_TYPE:
- i = strtol(argv[optind - 1], &end, 0);
+ i = strtol(optarg, &end, 0);
if (i < 0 || i > 255 || *end != '\0') {
- if (!strcasecmp(argv[optind - 1],
- BPDU_TYPE_CONFIG_STRING))
+ if (!strcasecmp(optarg, BPDU_TYPE_CONFIG_STRING))
stpinfo->type = BPDU_TYPE_CONFIG;
- else if (!strcasecmp(argv[optind - 1],
- BPDU_TYPE_TCN_STRING))
+ else if (!strcasecmp(optarg, BPDU_TYPE_TCN_STRING))
stpinfo->type = BPDU_TYPE_TCN;
else
- ebt_print_error("Bad --stp-type argument");
+ ebt_print_error2("Bad --stp-type argument");
} else
stpinfo->type = i;
break;
case EBT_STP_FLAGS:
- i = strtol(argv[optind - 1], &end, 0);
+ i = strtol(optarg, &end, 0);
if (i < 0 || i > 255 || *end != '\0') {
- if (!strcasecmp(argv[optind - 1],
- FLAG_TC_STRING))
+ if (!strcasecmp(optarg, FLAG_TC_STRING))
stpinfo->config.flags = FLAG_TC;
- else if (!strcasecmp(argv[optind - 1],
- FLAG_TC_ACK_STRING))
+ else if (!strcasecmp(optarg, FLAG_TC_ACK_STRING))
stpinfo->config.flags = FLAG_TC_ACK;
else
- ebt_print_error("Bad --stp-flags argument");
+ ebt_print_error2("Bad --stp-flags argument");
} else
stpinfo->config.flags = i;
break;
diff --git a/extensions/ebt_ulog.c b/extensions/ebt_ulog.c
index 4af42e2..5c762b2 100644
--- a/extensions/ebt_ulog.c
+++ b/extensions/ebt_ulog.c
@@ -1,3 +1,11 @@
+/* ebt_ulog
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * November, 2004
+ */
+
#define __need_time_t
#define __need_suseconds_t
#include <stdio.h>
@@ -65,59 +73,54 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
uloginfo = (struct ebt_ulog_info *)(*watcher)->data;
switch (c) {
case ULOG_PREFIX:
- if (ebt_check_inverse(optarg))
+ if (ebt_check_inverse2(optarg))
goto inverse_invalid;
- ebt_check_option(flags, OPT_PREFIX);
+ ebt_check_option2(flags, OPT_PREFIX);
if (strlen(optarg) > EBT_ULOG_PREFIX_LEN - 1)
ebt_print_error("Prefix too long for ulog-prefix");
strcpy(uloginfo->prefix, optarg);
break;
case ULOG_NLGROUP:
- if (ebt_check_inverse(optarg))
+ if (ebt_check_inverse2(optarg))
goto inverse_invalid;
- ebt_check_option(flags, OPT_NLGROUP);
+ ebt_check_option2(flags, OPT_NLGROUP);
i = strtoul(optarg, &end, 10);
if (*end != '\0')
- ebt_print_error("Problem with ulog-nlgroup: %s", optarg);
+ ebt_print_error2("Problem with ulog-nlgroup: %s", optarg);
if (i < 1 || i > EBT_ULOG_MAXNLGROUPS)
- ebt_print_error("the ulog-nlgroup number must be "
- "between 1 and 32");
+ ebt_print_error2("the ulog-nlgroup number must be between 1 and 32");
uloginfo->nlgroup = i - 1;
break;
case ULOG_CPRANGE:
- if (ebt_check_inverse(optarg))
+ if (ebt_check_inverse2(optarg))
goto inverse_invalid;
- ebt_check_option(flags, OPT_CPRANGE);
+ ebt_check_option2(flags, OPT_CPRANGE);
i = strtoul(optarg, &end, 10);
if (*end != '\0') {
if (strcasecmp(optarg, CP_NO_LIMIT_S))
- ebt_print_error("Problem with ulog-cprange: "
- "%s", optarg);
+ ebt_print_error2("Problem with ulog-cprange: %s", optarg);
i = CP_NO_LIMIT_N;
}
uloginfo->cprange = i;
break;
case ULOG_QTHRESHOLD:
- if (ebt_check_inverse(optarg))
+ if (ebt_check_inverse2(optarg))
goto inverse_invalid;
- ebt_check_option(flags, OPT_QTHRESHOLD);
+ ebt_check_option2(flags, OPT_QTHRESHOLD);
i = strtoul(optarg, &end, 10);
if (*end != '\0')
- ebt_print_error("Problem with ulog-qthreshold: %s",
- optarg);
+ ebt_print_error2("Problem with ulog-qthreshold: %s", optarg);
if (i > EBT_ULOG_MAX_QLEN)
- ebt_print_error("ulog-qthreshold argument %d exceeds "
- "the maximum of %d", i,
- EBT_ULOG_MAX_QLEN);
+ ebt_print_error2("ulog-qthreshold argument %d exceeds the maximum of %d", i, EBT_ULOG_MAX_QLEN);
uloginfo->qthreshold = i;
break;
case ULOG_ULOG:
- if (ebt_check_inverse(optarg))
+ if (ebt_check_inverse2(optarg))
goto inverse_invalid;
- ebt_check_option(flags, OPT_ULOG);
+ ebt_check_option2(flags, OPT_ULOG);
break;
default:
@@ -127,14 +130,13 @@ static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
inverse_invalid:
ebt_print_error("The use of '!' makes no sense for the ulog watcher");
- return 0;
+ return 1;
}
static void final_check(const struct ebt_u_entry *entry,
const struct ebt_entry_watcher *watcher, const char *name,
unsigned int hookmask, unsigned int time)
{
- return;
}
static void print(const struct ebt_u_entry *entry,
diff --git a/extensions/ebt_vlan.c b/extensions/ebt_vlan.c
index 0c94a66..21f2e22 100644
--- a/extensions/ebt_vlan.c
+++ b/extensions/ebt_vlan.c
@@ -1,33 +1,10 @@
-/*
- * Summary: ebt_vlan - IEEE 802.1Q extension module for userspace
- *
- * Description: 802.1Q Virtual LAN match support module for ebtables project.
- * Enables to match 802.1Q:
- * 1) VLAN-tagged frames by VLAN numeric identifier (12 - bits field)
- * 2) Priority-tagged frames by user_priority (3 bits field)
- * 3) Encapsulated Frame by ethernet protocol type/length
+/* ebt_vlan
*
* Authors:
- * Bart De Schuymer <bart.de.schuymer@pandora.be>
+ * Bart De Schuymer <bdschuym@pandora.be>
* Nick Fedchik <nick@fedchik.org.ua>
- * June, 2002
- *
- * License: GNU GPL
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
+ * June, 2002
*/
#include <stdio.h>
@@ -40,30 +17,19 @@
#include <linux/netfilter_bridge/ebt_vlan.h>
#include <linux/if_ether.h>
-
-#define GET_BITMASK(_MASK_) vlaninfo->bitmask & _MASK_
-#define SET_BITMASK(_MASK_) vlaninfo->bitmask |= _MASK_
-#define INV_FLAG(_inv_flag_) (vlaninfo->invflags & _inv_flag_) ? "! " : ""
-#define CHECK_IF_MISSING_VALUE if (optind > argc) ebt_print_error ("Missing %s value", opts[c].name);
-#define CHECK_INV_FLAG(_INDEX_) if (ebt_check_inverse (optarg)) vlaninfo->invflags |= _INDEX_;
-#define CHECK_RANGE(_RANGE_) if (_RANGE_) ebt_print_error ("Invalid %s range", opts[c].name);
-
#define NAME_VLAN_ID "id"
#define NAME_VLAN_PRIO "prio"
#define NAME_VLAN_ENCAP "encap"
-#define VLAN_ID 0
-#define VLAN_PRIO 1
-#define VLAN_ENCAP 2
+#define VLAN_ID '1'
+#define VLAN_PRIO '2'
+#define VLAN_ENCAP '3'
static struct option opts[] = {
- {EBT_VLAN_MATCH "-" NAME_VLAN_ID, required_argument, NULL,
- VLAN_ID},
- {EBT_VLAN_MATCH "-" NAME_VLAN_PRIO, required_argument, NULL,
- VLAN_PRIO},
- {EBT_VLAN_MATCH "-" NAME_VLAN_ENCAP, required_argument, NULL,
- VLAN_ENCAP},
- {NULL}
+ {"vlan-id" , required_argument, NULL, VLAN_ID},
+ {"vlan-prio" , required_argument, NULL, VLAN_PRIO},
+ {"vlan-encap", required_argument, NULL, VLAN_ENCAP},
+ { 0 }
};
/*
@@ -76,104 +42,67 @@ static struct option opts[] = {
struct ethertypeent *ethent;
-/*
- * Print out local help by "ebtables -h <match name>"
- */
-
static void print_help()
{
-#define HELP_TITLE "802.1Q VLAN extension"
-
- printf(HELP_TITLE " options:\n");
- printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_ID " %s" NAME_VLAN_ID
- " : VLAN-tagged frame identifier, 0,1-4096 (integer), default 1\n",
- OPT_VLAN_FLAGS & OPT_VLAN_ID ? "[!] " : "");
- printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_PRIO " %s" NAME_VLAN_PRIO
- " : Priority-tagged frame user_priority, 0-7 (integer), default 0\n",
- OPT_VLAN_FLAGS & OPT_VLAN_PRIO ? "[!] " : "");
- printf("--" EBT_VLAN_MATCH "-" NAME_VLAN_ENCAP " %s"
- NAME_VLAN_ENCAP
- " : Encapsulated frame type (hexadecimal), default IP (0800)\n",
- OPT_VLAN_FLAGS & OPT_VLAN_ENCAP ? "[!] " : "");
+ printf(
+"vlan options:\n"
+"--vlan-id [!] id : vlan-tagged frame identifier, 0,1-4096 (integer)\n"
+"--vlan-prio [!] prio : Priority-tagged frame's user priority, 0-7 (integer)\n"
+"--vlan-encap [!] encap : Encapsulated frame protocol (hexadecimal or name)\n");
}
-/*
- * Initialization function
- */
static void init(struct ebt_entry_match *match)
{
- struct ebt_vlan_info *vlaninfo =
- (struct ebt_vlan_info *) match->data;
- /*
- * Set initial values
- */
- vlaninfo->id = 1; /* Default VID for VLAN-tagged 802.1Q frames */
- vlaninfo->prio = 0;
- vlaninfo->encap = 0;
+ struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) match->data;
vlaninfo->invflags = 0;
vlaninfo->bitmask = 0;
}
-/*
- * Parse passed arguments values (ranges, flags, etc...)
- * int c - parameter number from static struct option opts[]
- * int argc - total amout of arguments (std argc value)
- * int argv - arguments (std argv value)
- * const struct ebt_u_entry *entry - default ebtables entry set
- * unsigned int *flags -
- * struct ebt_entry_match **match -
- */
-static int
-parse(int c,
- char **argv,
- int argc,
- const struct ebt_u_entry *entry,
- unsigned int *flags, struct ebt_entry_match **match)
+static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
+ unsigned int *flags, struct ebt_entry_match **match)
{
- struct ebt_vlan_info *vlaninfo =
- (struct ebt_vlan_info *) (*match)->data;
+ struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) (*match)->data;
char *end;
struct ebt_vlan_info local;
switch (c) {
case VLAN_ID:
- ebt_check_option(flags, OPT_VLAN_ID);
- CHECK_INV_FLAG(EBT_VLAN_ID);
- CHECK_IF_MISSING_VALUE;
- local.id = strtoul(argv[optind - 1], &end, 10);
- CHECK_RANGE(local.id > 4094 || *end != '\0');
+ ebt_check_option2(flags, OPT_VLAN_ID);
+ if (ebt_check_inverse2(optarg))
+ vlaninfo->invflags |= EBT_VLAN_ID;
+ local.id = strtoul(optarg, &end, 10);
+ if (local.id > 4094 || *end != '\0')
+ ebt_print_error2("Invalid --vlan-id range ('%s')", optarg);
vlaninfo->id = local.id;
- SET_BITMASK(EBT_VLAN_ID);
+ vlaninfo->bitmask |= EBT_VLAN_ID;
break;
-
case VLAN_PRIO:
- ebt_check_option(flags, OPT_VLAN_PRIO);
- CHECK_INV_FLAG(EBT_VLAN_PRIO);
- CHECK_IF_MISSING_VALUE;
- local.prio = strtoul(argv[optind - 1], &end, 10);
- CHECK_RANGE(local.prio >= 8 || *end != '\0');
+ ebt_check_option2(flags, OPT_VLAN_PRIO);
+ if (ebt_check_inverse2(optarg))
+ vlaninfo->invflags |= EBT_VLAN_PRIO;
+ local.prio = strtoul(optarg, &end, 10);
+ if (local.prio >= 8 || *end != '\0')
+ ebt_print_error2("Invalid --vlan-prio range ('%s')", optarg);
vlaninfo->prio = local.prio;
- SET_BITMASK(EBT_VLAN_PRIO);
+ vlaninfo->bitmask |= EBT_VLAN_PRIO;
break;
-
case VLAN_ENCAP:
- ebt_check_option(flags, OPT_VLAN_ENCAP);
- CHECK_INV_FLAG(EBT_VLAN_ENCAP);
- CHECK_IF_MISSING_VALUE;
- local.encap = strtoul(argv[optind - 1], &end, 16);
+ ebt_check_option2(flags, OPT_VLAN_ENCAP);
+ if (ebt_check_inverse2(optarg))
+ vlaninfo->invflags |= EBT_VLAN_ENCAP;
+ local.encap = strtoul(optarg, &end, 16);
if (*end != '\0') {
- ethent = getethertypebyname(argv[optind - 1]);
+ ethent = getethertypebyname(optarg);
if (ethent == NULL)
- ebt_print_error("Unknown %s encap",
- opts[c].name);
+ ebt_print_error("Unknown --vlan-encap value ('%s')", optarg);
local.encap = ethent->e_ethertype;
}
- CHECK_RANGE(local.encap < ETH_ZLEN);
+ if (local.encap < ETH_ZLEN)
+ ebt_print_error2("Invalid --vlan-encap range ('%s')", optarg);
vlaninfo->encap = htons(local.encap);
- SET_BITMASK(EBT_VLAN_ENCAP);
+ vlaninfo->bitmask |= EBT_VLAN_ENCAP;
break;
-
default:
return 0;
@@ -181,75 +110,34 @@ parse(int c,
return 1;
}
-/*
- * Final check - logical conditions
- */
-static void
-final_check(const struct ebt_u_entry *entry,
- const struct ebt_entry_match *match,
- const char *name, unsigned int hookmask, unsigned int time)
+static void final_check(const struct ebt_u_entry *entry,
+ const struct ebt_entry_match *match,
+ const char *name, unsigned int hookmask, unsigned int time)
{
-
- struct ebt_vlan_info *vlaninfo =
- (struct ebt_vlan_info *) match->data;
- /*
- * Specified proto isn't 802.1Q?
- */
if (entry->ethproto != ETH_P_8021Q || entry->invflags & EBT_IPROTO)
- ebt_print_error("For use 802.1Q extension the protocol "
- "must be specified as 802_1Q");
- /*
- * Check if specified vlan-encap=0x8100 (802.1Q Frame)
- * when vlan-encap specified.
- */
- if (GET_BITMASK(EBT_VLAN_ENCAP)) {
- if (vlaninfo->encap == htons(0x8100))
- ebt_print_error("Encapsulated frame type can not be "
- "802.1Q (0x8100)");
- }
-
- /*
- * Check if specified vlan-id=0 (priority-tagged frame condition)
- * when vlan-prio was specified.
- */
- if (GET_BITMASK(EBT_VLAN_PRIO)) {
- if (vlaninfo->id && GET_BITMASK(EBT_VLAN_ID))
- ebt_print_error("For use user_priority the specified "
- "vlan-id must be 0");
- }
+ ebt_print_error("For vlan filtering the protocol must be specified as 802_1Q");
+
+ /* Check if specified vlan-id=0 (priority-tagged frame condition)
+ * when vlan-prio was specified. */
+ /* I see no reason why a user should be prohibited to match on a perhaps impossible situation <BDS>
+ if (vlaninfo->bitmask & EBT_VLAN_PRIO &&
+ vlaninfo->id && vlaninfo->bitmask & EBT_VLAN_ID)
+ ebt_print_error("When setting --vlan-prio the specified --vlan-id must be 0");*/
}
-/*
- * Print line when listing rules by ebtables -L
- */
-static void
-print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match)
+static void print(const struct ebt_u_entry *entry,
+ const struct ebt_entry_match *match)
{
- struct ebt_vlan_info *vlaninfo =
- (struct ebt_vlan_info *) match->data;
+ struct ebt_vlan_info *vlaninfo = (struct ebt_vlan_info *) match->data;
- /*
- * Print VLAN ID if they are specified
- */
- if (GET_BITMASK(EBT_VLAN_ID)) {
- printf("--%s %s%d ",
- opts[VLAN_ID].name,
- INV_FLAG(EBT_VLAN_ID), vlaninfo->id);
+ if (vlaninfo->bitmask & EBT_VLAN_ID) {
+ printf("--vlan-id %s%d ", (vlaninfo->invflags & EBT_VLAN_ID) ? "! " : "", vlaninfo->id);
}
- /*
- * Print user priority if they are specified
- */
- if (GET_BITMASK(EBT_VLAN_PRIO)) {
- printf("--%s %s%d ",
- opts[VLAN_PRIO].name,
- INV_FLAG(EBT_VLAN_PRIO), vlaninfo->prio);
+ if (vlaninfo->bitmask & EBT_VLAN_PRIO) {
+ printf("--vlan-prio %s%d ", (vlaninfo->invflags & EBT_VLAN_PRIO) ? "! " : "", vlaninfo->prio);
}
- /*
- * Print encapsulated frame type if they are specified
- */
- if (GET_BITMASK(EBT_VLAN_ENCAP)) {
- printf("--%s %s",
- opts[VLAN_ENCAP].name, INV_FLAG(EBT_VLAN_ENCAP));
+ if (vlaninfo->bitmask & EBT_VLAN_ENCAP) {
+ printf("--vlan-encap %s", (vlaninfo->invflags & EBT_VLAN_ENCAP) ? "! " : "");
ethent = getethertypebynumber(ntohs(vlaninfo->encap));
if (ethent != NULL) {
printf("%s ", ethent->e_name);
@@ -259,47 +147,25 @@ print(const struct ebt_u_entry *entry, const struct ebt_entry_match *match)
}
}
-
-static int
-compare(const struct ebt_entry_match *vlan1,
- const struct ebt_entry_match *vlan2)
+static int compare(const struct ebt_entry_match *vlan1,
+ const struct ebt_entry_match *vlan2)
{
- struct ebt_vlan_info *vlaninfo1 =
- (struct ebt_vlan_info *) vlan1->data;
- struct ebt_vlan_info *vlaninfo2 =
- (struct ebt_vlan_info *) vlan2->data;
- /*
- * Compare argc
- */
+ struct ebt_vlan_info *vlaninfo1 = (struct ebt_vlan_info *) vlan1->data;
+ struct ebt_vlan_info *vlaninfo2 = (struct ebt_vlan_info *) vlan2->data;
+
if (vlaninfo1->bitmask != vlaninfo2->bitmask)
return 0;
- /*
- * Compare inv flags
- */
if (vlaninfo1->invflags != vlaninfo2->invflags)
return 0;
- /*
- * Compare VLAN ID if they are present
- */
- if (vlaninfo1->bitmask & EBT_VLAN_ID) {
- if (vlaninfo1->id != vlaninfo2->id)
- return 0;
- };
- /*
- * Compare VLAN Prio if they are present
- */
- if (vlaninfo1->bitmask & EBT_VLAN_PRIO) {
- if (vlaninfo1->prio != vlaninfo2->prio)
- return 0;
- };
- /*
- * Compare VLAN Encap if they are present
- */
- if (vlaninfo1->bitmask & EBT_VLAN_ENCAP) {
- if (vlaninfo1->encap != vlaninfo2->encap)
- return 0;
- };
-
+ if (vlaninfo1->bitmask & EBT_VLAN_ID &&
+ vlaninfo1->id != vlaninfo2->id)
+ return 0;
+ if (vlaninfo1->bitmask & EBT_VLAN_PRIO &&
+ vlaninfo1->prio != vlaninfo2->prio)
+ return 0;
+ if (vlaninfo1->bitmask & EBT_VLAN_ENCAP &&
+ vlaninfo1->encap != vlaninfo2->encap)
+ return 0;
return 1;
}
diff --git a/extensions/ebtable_broute.c b/extensions/ebtable_broute.c
index 3c00962..5259355 100644
--- a/extensions/ebtable_broute.c
+++ b/extensions/ebtable_broute.c
@@ -1,3 +1,11 @@
+/* ebtable_broute
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * April, 2002
+ */
+
#include <stdio.h>
#include "../include/ebtables_u.h"
diff --git a/extensions/ebtable_filter.c b/extensions/ebtable_filter.c
index 08f5033..e41fb84 100644
--- a/extensions/ebtable_filter.c
+++ b/extensions/ebtable_filter.c
@@ -1,3 +1,11 @@
+/* ebtable_filter
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * April, 2002
+ */
+
#include <stdio.h>
#include "../include/ebtables_u.h"
diff --git a/extensions/ebtable_nat.c b/extensions/ebtable_nat.c
index d64e21d..b21c9dd 100644
--- a/extensions/ebtable_nat.c
+++ b/extensions/ebtable_nat.c
@@ -1,3 +1,11 @@
+/* ebtable_nat
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ * April, 2002
+ */
+
#include <stdio.h>
#include "../include/ebtables_u.h"
diff --git a/include/ebtables_u.h b/include/ebtables_u.h
index 5632ec1..24c5045 100644
--- a/include/ebtables_u.h
+++ b/include/ebtables_u.h
@@ -256,6 +256,9 @@ void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry,
void ebt_delete_rule(struct ebt_u_replace *replace,
struct ebt_u_entry *new_entry, int begin, int end);
void ebt_zero_counters(struct ebt_u_replace *replace);
+void ebt_change_counters(struct ebt_u_replace *replace,
+ struct ebt_u_entry *new_entry, int begin, int end,
+ struct ebt_counter *cnt);
void ebt_new_chain(struct ebt_u_replace *replace, const char *name, int policy);
void ebt_delete_chain(struct ebt_u_replace *replace);
void ebt_rename_chain(struct ebt_u_replace *replace, const char *name);
@@ -284,7 +287,8 @@ void ebt_deliver_table(struct ebt_u_replace *repl);
extern int ebt_invert;
void ebt_check_option(unsigned int *flags, unsigned int mask);
-int ebt_check_inverse(const char option[]);
+#define ebt_check_inverse(arg) _ebt_check_inverse(arg, argc, argv)
+int _ebt_check_inverse(const char option[], int argc, char **argv);
void ebt_print_mac(const char *mac);
void ebt_print_mac_and_mask(const char *mac, const char *mask);
int ebt_get_mac_and_mask(char *from, char *to, char *mask);
@@ -299,6 +303,21 @@ struct ethertypeent *parseethertypebynumber(int type);
#define ebt_print_bug(format, args...) \
__ebt_print_bug(__FILE__, __LINE__, format, ##args)
#define ebt_print_error(format,args...) __ebt_print_error(format, ##args);
+#define ebt_print_error2(format, args...) {__ebt_print_error(format, ##args); \
+ return -1;}
+#define ebt_check_option2(flags,mask) \
+({ebt_check_option(flags,mask); \
+ if (ebt_errormsg[0] != '\0') \
+ return -1;})
+#define ebt_check_inverse2(option) \
+({int __ret = ebt_check_inverse(option); \
+if (ebt_errormsg[0] != '\0') \
+ return -1; \
+if (!optarg) { \
+ __ebt_print_error("Option without (mandatory) argument"); \
+ return -1; \
+} \
+__ret;})
#define ebt_print_memory() {printf("Ebtables: " __FILE__ \
" %s %d :Out of memory.\n", __FUNCTION__, __LINE__); exit(-1);}
@@ -308,6 +327,7 @@ struct ethertypeent *parseethertypebynumber(int type);
#define CNT_ADD 2
#define CNT_OWRITE 3
#define CNT_ZERO 4
+#define CNT_CHANGE 5
extern const char *ebt_hooknames[NF_BR_NUMHOOKS];
extern const char *ebt_standard_targets[NUM_STANDARD_TARGETS];
diff --git a/libebtc.c b/libebtc.c
index ff1e14c..a0dabde 100644
--- a/libebtc.c
+++ b/libebtc.c
@@ -1,4 +1,3 @@
-
/*
* libebtc.c, January 2004
*
@@ -260,8 +259,8 @@ void ebt_reinit_extensions()
strcpy(m->m->u.name, m->name);
m->m->match_size = EBT_ALIGN(m->size);
m->used = 0;
- m->flags = 0;
}
+ m->flags = 0; /* An error can occur before used is set, while flags is changed. */
m->init(m->m);
}
for (w = ebt_watchers; w; w = w->next) {
@@ -273,8 +272,8 @@ void ebt_reinit_extensions()
strcpy(w->w->u.name, w->name);
w->w->watcher_size = EBT_ALIGN(w->size);
w->used = 0;
- w->flags = 0;
}
+ w->flags = 0;
w->init(w->w);
}
for (t = ebt_targets; t; t = t->next) {
@@ -286,8 +285,8 @@ void ebt_reinit_extensions()
strcpy(t->t->u.name, t->name);
t->t->target_size = EBT_ALIGN(t->size);
t->used = 0;
- t->flags = 0;
}
+ t->flags = 0;
t->init(t->t);
}
}
@@ -777,6 +776,38 @@ void ebt_add_rule(struct ebt_u_replace *replace, struct ebt_u_entry *new_entry,
}
}
+static int check_and_change_rule_number(struct ebt_u_replace *replace,
+ struct ebt_u_entry *new_entry, int *begin, int *end)
+{
+ struct ebt_u_entries *entries = ebt_to_chain(replace);
+
+ if (*begin < 0)
+ *begin += entries->nentries + 1;
+ if (*end < 0)
+ *end += entries->nentries + 1;
+
+ if (*begin < 0 || *begin > *end || *end > entries->nentries) {
+ ebt_print_error("Sorry, wrong rule numbers");
+ return -1;
+ }
+
+ if ((*begin * *end == 0) && (*begin + *end != 0))
+ ebt_print_bug("begin and end should be either both zero, "
+ "either both non-zero");
+ if (*begin != 0 && *end != 0) {
+ (*begin)--;
+ (*end)--;
+ } else {
+ *begin = ebt_check_rule_exists(replace, new_entry);
+ *end = *begin;
+ if (*begin == -1) {
+ ebt_print_error("Sorry, rule does not exist");
+ return -1;
+ }
+ }
+ return 0;
+}
+
/* Delete a rule or rules
* begin == end == 0: delete the rule corresponding to new_entry
*
@@ -792,30 +823,8 @@ void ebt_delete_rule(struct ebt_u_replace *replace,
struct ebt_cntchanges *cc = replace->counterchanges;
struct ebt_cntchanges **prev_cc = &(replace->counterchanges);
- if (begin < 0)
- begin += entries->nentries + 1;
- if (end < 0)
- end += entries->nentries + 1;
-
- if (begin < 0 || begin > end || end > entries->nentries) {
- ebt_print_error("Sorry, wrong rule numbers");
+ if (check_and_change_rule_number(replace, new_entry, &begin, &end))
return;
- }
-
- if ((begin * end == 0) && (begin + end != 0))
- ebt_print_bug("begin and end should be either both zero, "
- "either both non-zero");
- if (begin != 0 && end != 0) {
- begin--;
- end--;
- } else {
- begin = ebt_check_rule_exists(replace, new_entry);
- end = begin;
- if (begin == -1) {
- ebt_print_error("Sorry, rule does not exist");
- return;
- }
- }
/* We're deleting rules */
nr_deletes = end - begin + 1;
@@ -886,6 +895,64 @@ void ebt_delete_rule(struct ebt_u_replace *replace,
}
}
+/* Change the counters of a rule or rules
+ * begin == end == 0: change counters of the rule corresponding to new_entry
+ *
+ * The first rule has rule nr 1, the last rule has rule nr -1, etc.
+ * This function expects the ebt_{match,watcher,target} members of new_entry
+ * to contain pointers to ebt_u_{match,watcher,target}. */
+void ebt_change_counters(struct ebt_u_replace *replace,
+ struct ebt_u_entry *new_entry, int begin, int end,
+ struct ebt_counter *cnt)
+{
+ int i, j;
+ struct ebt_u_entry *u_e;
+ struct ebt_u_entries *entries = ebt_to_chain(replace);
+ struct ebt_cntchanges *cc = replace->counterchanges;
+ struct ebt_cntchanges **prev_cc = &(replace->counterchanges);
+
+ if (check_and_change_rule_number(replace, new_entry, &begin, &end))
+ return;
+
+ for (i = 0; i < replace->selected_chain; i++) {
+ if (i < NF_BR_NUMHOOKS && !(replace->valid_hooks & (1 << i)))
+ continue;
+ j = ebt_nr_to_chain(replace, i)->nentries;
+ while (j) {
+ if (cc->type != CNT_DEL)
+ j--;
+ prev_cc = &(cc->next);
+ cc = cc->next;
+ }
+ }
+ i = begin;
+ while (i) {
+ if (cc->type != CNT_DEL)
+ i--;
+ prev_cc = &(cc->next);
+ cc = cc->next;
+ }
+ i = end - begin + 1;
+ while (i) {
+ if (cc->type != CNT_DEL) {
+ i--;
+ /* A -C after a -A remains a -A */
+ if (cc->type != CNT_ADD && cc->type != CNT_OWRITE)
+ cc->type = CNT_CHANGE;
+ }
+ prev_cc = &(cc->next);
+ cc = cc->next;
+ }
+ u_e = entries->entries;
+ for (i = 0; i < begin; i++)
+ u_e = u_e->next;
+ i = end - begin + 1;
+ while(i--) {
+ u_e->cnt = *cnt;
+ u_e = u_e->next;
+ }
+}
+
/* Selected_chain == -1 : zero all counters
* Otherwise, zero the counters of selected_chain */
void ebt_zero_counters(struct ebt_u_replace *replace)
diff --git a/useful_functions.c b/useful_functions.c
index a36062e..0cd3d51 100644
--- a/useful_functions.c
+++ b/useful_functions.c
@@ -39,11 +39,9 @@ const unsigned char msk_type_broadcast[ETH_ALEN] = {255,255,255,255,255,255};
const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01,0x80,0xc2,0,0,0};
const unsigned char msk_type_bridge_group[ETH_ALEN] = {255,255,255,255,255,255};
-/*
- * 0: default, print only 2 digits if necessary
+/* 0: default, print only 2 digits if necessary
* 2: always print 2 digits, a printed mac address
- * then always has the same length
- */
+ * then always has the same length */
int ebt_printstyle_mac;
void ebt_print_mac(const char *mac)
@@ -82,9 +80,7 @@ void ebt_print_mac_and_mask(const char *mac, const char *mask)
}
}
-/*
- * Checks the type for validity and calls getethertypebynumber()
- */
+/* Checks the type for validity and calls getethertypebynumber(). */
struct ethertypeent *parseethertypebynumber(int type)
{
if (type < 1536)
@@ -94,10 +90,7 @@ struct ethertypeent *parseethertypebynumber(int type)
return getethertypebynumber(type);
}
-/*
- * put the mac address into 6 (ETH_ALEN) bytes
- * returns 0 on success
- */
+/* Put the mac address into 6 (ETH_ALEN) bytes returns 0 on success. */
int ebt_get_mac_and_mask(char *from, char *to, char *mask)
{
char *p;
@@ -139,23 +132,25 @@ int ebt_get_mac_and_mask(char *from, char *to, char *mask)
return 0;
}
-/*
- * 0: default
- * 1: the inverse '!' of the option has already been specified
- */
+/* 0: default
+ * 1: the inverse '!' of the option has already been specified */
int ebt_invert = 0;
/*
* Check if the inverse of the option is specified. This is used
- * in the parse functions of the extensions and ebtables.c.
+ * in the parse functions of the extensions and ebtables.c
*/
-int ebt_check_inverse(const char option[])
+int _ebt_check_inverse(const char option[], int argc, char **argv)
{
if (!option)
return ebt_invert;
if (strcmp(option, "!") == 0) {
if (ebt_invert == 1)
- ebt_print_error("double use of '!' not allowed");
+ ebt_print_error("Double use of '!' not allowed");
+ if (optind >= argc)
+ optarg = NULL;
+ else
+ optarg = argv[optind];
optind++;
ebt_invert = 1;
return 1;
@@ -163,10 +158,8 @@ int ebt_check_inverse(const char option[])
return ebt_invert;
}
-/*
- * Make sure the same option wasn't specified twice. This is used
- * in the parse functions of the extensions and ebtables.c.
- */
+/* Make sure the same option wasn't specified twice. This is used
+ * in the parse functions of the extensions and ebtables.c */
void ebt_check_option(unsigned int *flags, unsigned int mask)
{
if (*flags & mask)
@@ -174,9 +167,7 @@ void ebt_check_option(unsigned int *flags, unsigned int mask)
*flags |= mask;
}
-/*
- * put the ip string into 4 bytes
- */
+/* Put the ip string into 4 bytes. */
static int undot_ip(char *ip, unsigned char *ip2)
{
char *p, *q, *end;
@@ -206,9 +197,7 @@ static int undot_ip(char *ip, unsigned char *ip2)
return 0;
}
-/*
- * put the mask into 4 bytes
- */
+/* Put the mask into 4 bytes. */
static int ip_mask(char *mask, unsigned char *mask2)
{
char *end;
@@ -231,9 +220,8 @@ static int ip_mask(char *mask, unsigned char *mask2)
return 0;
}
-/*
- * set the ip mask and ip address
- */
+/* Set the ip mask and ip address. Callers should check ebt_errormsg[0].
+ * The string pointed to by address can be altered. */
void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
{
char *p;
@@ -241,19 +229,21 @@ void ebt_parse_ip_address(char *address, uint32_t *addr, uint32_t *msk)
/* first the mask */
if ((p = strrchr(address, '/')) != NULL) {
*p = '\0';
- if (ip_mask(p + 1, (unsigned char *)msk))
- ebt_print_error("Problem with the IP mask");
+ if (ip_mask(p + 1, (unsigned char *)msk)) {
+ ebt_print_error("Problem with the IP mask '%s'", p + 1);
+ return;
+ }
} else
*msk = 0xFFFFFFFF;
- if (undot_ip(address, (unsigned char *)addr))
- ebt_print_error("Problem with the IP address");
+ if (undot_ip(address, (unsigned char *)addr)) {
+ ebt_print_error("Problem with the IP address '%s'", address);
+ return;
+ }
*addr = *addr & *msk;
}
-/*
- * transform the ip mask into a string ready for output
- */
+/* Transform the ip mask into a string ready for output. */
char *ebt_mask_to_dotted(uint32_t mask)
{
int i;
@@ -269,7 +259,7 @@ char *ebt_mask_to_dotted(uint32_t mask)
}
i = 32;
- bits = 0xFFFFFFFEL; /* case 0xFFFFFFFF has just been dealt with */
+ bits = 0xFFFFFFFEL; /* Case 0xFFFFFFFF has just been dealt with */
while (--i >= 0 && maskaddr != bits)
bits <<= 1;
@@ -278,7 +268,7 @@ char *ebt_mask_to_dotted(uint32_t mask)
else if (!i)
*buf = '\0';
else
- /* mask was not a decent combination of 1's and 0's */
+ /* Mask was not a decent combination of 1's and 0's */
sprintf(buf, "/%d.%d.%d.%d", ((unsigned char *)&mask)[0],
((unsigned char *)&mask)[1], ((unsigned char *)&mask)[2],
((unsigned char *)&mask)[3]);