blob: 1c7d9323cb38caf556a5ec295b2d43e2042efd2c [file] [log] [blame]
--- ebtables-v2.0.3/Makefile Tue Apr 1 22:12:30 2003
+++ ebtables-v2.0.4/Makefile Mon Apr 21 17:56:21 2003
@@ -1,7 +1,7 @@
# ebtables Makefile
PROGNAME:=ebtables
-PROGVERSION:=2.0.3
+PROGVERSION:=2.0.4
PROGDATE:=April\ 2003
MANDIR?=/usr/local/man
@@ -14,7 +14,7 @@
KERNEL_INCLUDES?=include/
-ETHERTYPESPATH?=/etc/
+ETHERTYPESPATH?=/etc
ETHERTYPESFILE:=$(ETHERTYPESPATH)/ethertypes
BINPATH?=/sbin/
--- ebtables-v2.0.3/ebtables.c Tue Apr 1 20:08:15 2003
+++ ebtables-v2.0.4/ebtables.c Sat May 24 23:34:22 2003
@@ -79,6 +79,7 @@
{ "Lc" , no_argument , 0, 4 },
{ "Ln" , no_argument , 0, 5 },
{ "Lx" , no_argument , 0, 6 },
+ { "Lmac2" , no_argument , 0, 12 },
{ "zero" , optional_argument, 0, 'Z' },
{ "flush" , optional_argument, 0, 'F' },
{ "policy" , required_argument, 0, 'P' },
@@ -367,6 +368,7 @@
tables = t;
}
+const char *modprobe = NULL;
/*
* blatently stolen (again) from iptables.c userspace program
* find out where the modprobe utility is located
@@ -397,7 +399,7 @@
return NULL;
}
-int ebtables_insmod(const char *modname, const char *modprobe)
+int ebtables_insmod(const char *modname)
{
char *buf = NULL;
char *argv[3];
@@ -465,9 +467,33 @@
* we use replace.flags, so we can't use the following values:
* 0x01 == OPT_COMMAND, 0x02 == OPT_TABLE, 0x100 == OPT_ZERO
*/
-#define LIST_N 0x04
-#define LIST_C 0x08
-#define LIST_X 0x10
+#define LIST_N 0x04
+#define LIST_C 0x08
+#define LIST_X 0x10
+#define LIST_MAC2 0x20
+
+void print_mac(const char *mac)
+{
+ if (replace.flags & LIST_MAC2) {
+ int j;
+ for (j = 0; j < ETH_ALEN; j++)
+ printf("%02x%s", (unsigned char)mac[j],
+ (j==ETH_ALEN-1) ? "" : ":");
+ } else
+ printf("%s", ether_ntoa((struct ether_addr *) mac));
+}
+
+void print_mac_and_mask(const char *mac, const char *mask)
+{
+ char hlpmsk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+ print_mac(mac);
+ if (memcmp(mask, hlpmsk, 6)) {
+ printf("/");
+ print_mac(mask);
+ }
+}
+
/*
* helper function for list_rules()
*/
@@ -535,8 +561,6 @@
}
}
if (hlp->bitmask & EBT_SOURCEMAC) {
- char hlpmsk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
printf("-s ");
if (hlp->invflags & EBT_ISOURCE)
printf("! ");
@@ -555,19 +579,11 @@
printf("Broadcast");
goto endsrc;
}
- printf("%s", ether_ntoa((struct ether_addr *)
- hlp->sourcemac));
- if (memcmp(hlp->sourcemsk, hlpmsk, 6)) {
- printf("/");
- printf("%s", ether_ntoa((struct ether_addr *)
- hlp->sourcemsk));
- }
+ print_mac_and_mask(hlp->sourcemac, hlp->sourcemsk);
endsrc:
printf(" ");
}
if (hlp->bitmask & EBT_DESTMAC) {
- char hlpmsk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
printf("-d ");
if (hlp->invflags & EBT_IDEST)
printf("! ");
@@ -586,13 +602,7 @@
printf("Broadcast");
goto enddst;
}
- printf("%s", ether_ntoa((struct ether_addr *)
- hlp->destmac));
- if (memcmp(hlp->destmsk, hlpmsk, 6)) {
- printf("/");
- printf("%s", ether_ntoa((struct ether_addr *)
- hlp->destmsk));
- }
+ print_mac_and_mask(hlp->destmac, hlp->destmsk);
enddst:
printf(" ");
}
@@ -1081,7 +1091,7 @@
/*
* handle '-D chain rulenr' command
*/
- if (rule_nr != -1) {
+ if (rule_nr != 0) {
if (rule_nr > entries->nentries)
return -1;
/*
@@ -1186,12 +1196,12 @@
struct ebt_u_watcher_list *w_l;
struct ebt_u_entries *entries = to_chain(), *entries2;
- if (rule_nr != -1) { /* command -I */
- if (--rule_nr > entries->nentries)
- print_error("rule nr too high: %d > %d", rule_nr + 1,
- entries->nentries + 1);
- } else
- rule_nr = entries->nentries;
+ if (rule_nr <= 0)
+ rule_nr += entries->nentries;
+ else
+ rule_nr--;
+ if (rule_nr > entries->nentries || rule_nr < 0)
+ print_error("The specified rule number is incorrect");
/*
* we're adding one rule
*/
@@ -1282,6 +1292,14 @@
struct ebt_u_entry **u_e, *u_e2;
struct ebt_u_entries *entries = to_chain(), *entries2;
+ if (begin < 0)
+ begin += entries->nentries + 1;
+ if (end < 0)
+ end += entries->nentries + 1;
+
+ if (begin < 0 || begin > end || end > entries->nentries)
+ print_error("Sorry, wrong rule numbers");
+
if ((begin = check_rule_exists(begin)) == -1 ||
(end = check_rule_exists(end)) == -1)
print_error("Sorry, rule does not exist");
@@ -1535,24 +1553,22 @@
if (colon) {
*colon = '\0';
if (*(colon + 1) == '\0')
- *rule_nr_end = -1;
+ *rule_nr_end = -1; /* until the last rule */
else {
*rule_nr_end = strtol(colon + 1, &buffer, 10);
- if (*buffer != '\0' || *rule_nr_end < 0)
+ if (*buffer != '\0' || *rule_nr_end == 0)
return -1;
}
}
if (colon == argv)
- *rule_nr = 1;
+ *rule_nr = 1; /* beginning with the first rule */
else {
*rule_nr = strtol(argv, &buffer, 10);
- if (*buffer != '\0' || *rule_nr < 0)
+ if (*buffer != '\0' || *rule_nr == 0)
return -1;
}
if (!colon)
*rule_nr_end = *rule_nr;
- if (*rule_nr_end != -1 && *rule_nr > *rule_nr_end)
- return -1;
return 0;
}
@@ -1576,7 +1592,7 @@
*flags |= mask;
}
-static void get_kernel_table(const char *modprobe)
+static void get_kernel_table()
{
if ( !(table = find_table(replace.name)) )
print_error("Bad table name");
@@ -1584,7 +1600,7 @@
* get the kernel's information
*/
if (get_table(&replace)) {
- ebtables_insmod("ebtables", modprobe);
+ ebtables_insmod("ebtables");
if (get_table(&replace))
print_error("The kernel doesn't support the ebtables "
"%s table", replace.name);
@@ -1620,15 +1636,14 @@
*/
int zerochain = -1;
int policy = 0;
- int rule_nr = -1; /* used for -[D,I] */
- int rule_nr_end = -1; /* used for -I */
+ int rule_nr = 0; /* used for -[D,I] */
+ int rule_nr_end = 0; /* used for -I */
struct ebt_u_target *t;
struct ebt_u_match *m;
struct ebt_u_watcher *w;
struct ebt_u_match_list *m_l;
struct ebt_u_watcher_list *w_l;
struct ebt_u_entries *entries;
- const char *modprobe = NULL;
opterr = 0;
@@ -1674,7 +1689,7 @@
if (replace.flags & OPT_COMMAND)
print_error("Multiple commands not allowed");
replace.flags |= OPT_COMMAND;
- get_kernel_table(modprobe);
+ get_kernel_table();
if (optarg[0] == '-' || !strcmp(optarg, "!"))
print_error("No chain name specified");
if (c == 'N') {
@@ -1758,7 +1773,8 @@
}
if (c == 'D' && optind < argc &&
- argv[optind][0] != '-') {
+ (argv[optind][0] != '-' ||
+ (argv[optind][1] >= '0' && argv[optind][1] <= '9'))) {
if (parse_delete_rule(argv[optind],
&rule_nr, &rule_nr_end))
print_error("Problem with the "
@@ -1766,11 +1782,12 @@
optind++;
}
if (c == 'I') {
- if (optind >= argc || argv[optind][0] == '-')
+ if (optind >= argc || (argv[optind][0] == '-' &&
+ (argv[optind][1] < '0' || argv[optind][1] > '9')))
print_error("No rulenr for -I"
" specified");
rule_nr = strtol(argv[optind], &buffer, 10);
- if (*buffer != '\0' || rule_nr < 0)
+ if (*buffer != '\0')
print_error("Problem with the "
"specified rule number");
optind++;
@@ -1812,7 +1829,7 @@
" not allowed");
replace.flags |= OPT_COMMAND;
}
- get_kernel_table(modprobe);
+ get_kernel_table();
i = -1;
if (optarg) {
if ( (i = get_hooknr(optarg)) == -1 )
@@ -2108,6 +2125,12 @@
print_error("--Lx not compatible with --Ln");
replace.flags |= LIST_X;
break;
+ case 12 : /* Lmac2 */
+ check_option(&replace.flags, LIST_MAC2);
+ if (replace.command != 'L')
+ print_error("Use --Lmac2 with -L");
+ replace.flags |= LIST_MAC2;
+ break;
case 8 : /* atomic-commit */
replace.command = c;
if (replace.flags & OPT_COMMAND)
@@ -2136,7 +2159,6 @@
* possible memory leak here
*/
replace.filename = NULL;
- ebtables_insmod("ebtables", modprobe);
break;
case 7 : /* atomic-init */
case 10: /* atomic-save */
@@ -2153,7 +2175,7 @@
tmp = replace.filename;
/* get the kernel table */
replace.filename = NULL;
- get_kernel_table(modprobe);
+ get_kernel_table();
replace.filename = tmp;
}
if (replace.nentries) {
@@ -2320,11 +2342,8 @@
e = e->next;
}
}
- } else if (replace.command == 'D') {
- if (rule_nr != -1 && rule_nr_end == -1)
- rule_nr_end = entries->nentries;
+ } else if (replace.command == 'D')
delete_rule(rule_nr, rule_nr_end);
- }
/*
* commands -N, -E, -X, --atomic-commit, --atomic-commit, --atomic-save,
* --init-table fall through
--- ebtables-v2.0.3/communication.c Tue Apr 1 20:08:23 2003
+++ ebtables-v2.0.4/communication.c Sun May 4 18:54:44 2003
@@ -263,10 +263,19 @@
/* give the data to the kernel */
optlen = sizeof(struct ebt_replace) + repl->entries_size;
get_sockfd();
- if (setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES, repl, optlen))
- print_error("The kernel doesn't support a certain ebtables"
- " extension, consider recompiling your kernel or insmod"
- " the extension");
+ if (!setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES, repl, optlen))
+ return;
+ if (u_repl->command == 8) { /* the ebtables module may not
+ * yet be loaded with --atomic-commit */
+ ebtables_insmod("ebtables");
+ if (!setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES,
+ repl, optlen))
+ return;
+ }
+
+ print_error("The kernel doesn't support a certain ebtables"
+ " extension, consider recompiling your kernel or insmod"
+ " the extension");
}
static void store_counters_in_file(char *filename, struct ebt_u_replace *repl)
@@ -323,6 +332,7 @@
* So, we just copy
*/
new->pcnt = old->pcnt;
+ new->bcnt = old->bcnt;
/* we've used an old counter */
old++;
/* we've set a new counter */
--- ebtables-v2.0.3/extensions/ebt_arp.c Fri Jan 10 00:20:17 2003
+++ ebtables-v2.0.4/extensions/ebt_arp.c Sun May 25 11:58:48 2003
@@ -4,6 +4,7 @@
#include <getopt.h>
#include "../include/ebtables_u.h"
#include "../include/ethernetdb.h"
+#include <linux/if_ether.h>
#include <linux/netfilter_bridge/ebt_arp.h>
#define ARP_OPCODE '1'
@@ -11,6 +12,8 @@
#define ARP_PTYPE '3'
#define ARP_IP_S '4'
#define ARP_IP_D '5'
+#define ARP_MAC_S '6'
+#define ARP_MAC_D '7'
static struct option opts[] =
{
{ "arp-opcode" , required_argument, 0, ARP_OPCODE },
@@ -19,6 +22,8 @@
{ "arp-ptype" , required_argument, 0, ARP_PTYPE },
{ "arp-ip-src" , required_argument, 0, ARP_IP_S },
{ "arp-ip-dst" , required_argument, 0, ARP_IP_D },
+ { "arp-mac-src" , required_argument, 0, ARP_MAC_S },
+ { "arp-mac-dst" , required_argument, 0, ARP_MAC_D },
{ 0 }
};
@@ -43,14 +48,16 @@
printf(
"arp options:\n"
-"--arp-opcode opcode : ARP opcode (integer or string)\n"
-"--arp-htype type : ARP hardware type (integer or string)\n"
-"--arp-ptype type : ARP protocol type (hexadecimal or string)\n"
-"--arp-ip-src [!] address[/mask]: ARP IP source specification\n"
-"--arp-ip-dst [!] address[/mask]: ARP IP target specification\n"
+"--arp-opcode opcode : ARP opcode (integer or string)\n"
+"--arp-htype type : ARP hardware type (integer or string)\n"
+"--arp-ptype type : ARP protocol type (hexadecimal or string)\n"
+"--arp-ip-src [!] address[/mask]: ARP IP source specification\n"
+"--arp-ip-dst [!] address[/mask]: ARP IP target specification\n"
+"--arp-mac-src [!] address[/mask]: ARP MAC source specification\n"
+"--arp-mac-dst [!] address[/mask]: ARP MAC target specification\n"
" opcode strings: \n");
for (i = 0; i < NUMOPCODES; i++)
- printf("%d = %s\n", i + 1, opcodes[i]);
+ printf(" %d = %s\n", i + 1, opcodes[i]);
printf(
" hardware type string: 1 = Ethernet\n"
" protocol type string: see "_PATH_ETHERTYPES"\n");
@@ -67,11 +74,16 @@
/* defined in ebt_ip.c */
void parse_ip_address(char *address, uint32_t *addr, uint32_t *msk);
+/* defined in ebtables.c */
+int getmac_and_mask(char *from, char *to, char *mask);
+
#define OPT_OPCODE 0x01
#define OPT_HTYPE 0x02
#define OPT_PTYPE 0x04
#define OPT_IP_S 0x08
#define OPT_IP_D 0x10
+#define OPT_MAC_S 0x20
+#define OPT_MAC_D 0x40
static int parse(int c, char **argv, int argc, const struct ebt_u_entry *entry,
unsigned int *flags, struct ebt_entry_match **match)
{
@@ -80,6 +92,8 @@
char *end;
uint32_t *addr;
uint32_t *mask;
+ char *maddr;
+ char *mmask;
switch (c) {
case ARP_OPCODE:
@@ -172,6 +186,32 @@
print_error("Missing ARP IP address argument");
parse_ip_address(argv[optind - 1], addr, mask);
break;
+
+ case ARP_MAC_S:
+ case ARP_MAC_D:
+ if (c == ARP_MAC_S) {
+ check_option(flags, OPT_MAC_S);
+ maddr = arpinfo->smaddr;
+ mmask = arpinfo->smmsk;
+ arpinfo->bitmask |= EBT_ARP_SRC_MAC;
+ } else {
+ check_option(flags, OPT_MAC_D);
+ maddr = arpinfo->dmaddr;
+ mmask = arpinfo->dmmsk;
+ arpinfo->bitmask |= EBT_ARP_DST_MAC;
+ }
+ if (check_inverse(optarg)) {
+ if (c == ARP_MAC_S)
+ arpinfo->invflags |= EBT_ARP_SRC_MAC;
+ else
+ arpinfo->invflags |= EBT_ARP_DST_MAC;
+ }
+ if (optind > argc)
+ print_error("Missing ARP MAC address argument");
+ if (getmac_and_mask(argv[optind - 1], maddr, mmask))
+ print_error("Problem with ARP MAC address argument");
+ break;
+
default:
return 0;
}
@@ -243,6 +283,20 @@
(i == 3) ? "" : ".");
printf("%s ", mask_to_dotted(arpinfo->dmsk));
}
+ if (arpinfo->bitmask & EBT_ARP_SRC_MAC) {
+ printf("--arp-mac-src ");
+ if (arpinfo->invflags & EBT_ARP_SRC_MAC)
+ printf("! ");
+ print_mac_and_mask(arpinfo->smaddr, arpinfo->smmsk);
+ printf(" ");
+ }
+ if (arpinfo->bitmask & EBT_ARP_DST_MAC) {
+ printf("--arp-mac-dst ");
+ if (arpinfo->invflags & EBT_ARP_DST_MAC)
+ printf("! ");
+ print_mac_and_mask(arpinfo->dmaddr, arpinfo->dmmsk);
+ printf(" ");
+ }
}
static int compare(const struct ebt_entry_match *m1,
@@ -277,6 +331,18 @@
if (arpinfo1->daddr != arpinfo2->daddr)
return 0;
if (arpinfo1->dmsk != arpinfo2->dmsk)
+ return 0;
+ }
+ if (arpinfo1->bitmask & EBT_ARP_SRC_MAC) {
+ if (arpinfo1->smaddr != arpinfo2->smaddr)
+ return 0;
+ if (arpinfo1->smmsk != arpinfo2->smmsk)
+ return 0;
+ }
+ if (arpinfo1->bitmask & EBT_ARP_DST_MAC) {
+ if (arpinfo1->dmaddr != arpinfo2->dmaddr)
+ return 0;
+ if (arpinfo1->dmmsk != arpinfo2->dmmsk)
return 0;
}
return 1;
--- /dev/null Thu Aug 24 11:00:32 2000
+++ ebtables-v2.0.4/extensions/ebt_pkttype.c Thu May 1 13:59:15 2003
@@ -0,0 +1,136 @@
+/*
+ * ebtables ebt_pkttype
+ *
+ * Authors:
+ * Bart De Schuymer <bdschuym@pandora.be>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <netdb.h>
+#include "../include/ebtables_u.h"
+#include <linux/if_packet.h>
+#include <linux/netfilter_bridge/ebt_pkttype.h>
+
+char *classes[] =
+{
+ "host",
+ "broadcast",
+ "multicast",
+ "otherhost",
+ "outgoing",
+ "loopback",
+ "fastroute",
+ "\0"
+};
+
+static struct option opts[] =
+{
+ { "pkttype-type" , required_argument, 0, '1' },
+ { 0 }
+};
+
+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");
+}
+
+static void init(struct ebt_entry_match *match)
+{
+ struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data;
+
+ pt->invert = 0;
+}
+
+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_pkttype_info *ptinfo = (struct ebt_pkttype_info *)(*match)->data;
+ char *end;
+ long int i;
+
+ switch (c) {
+ case '1':
+ check_option(flags, 1);
+ if (check_inverse(optarg))
+ ptinfo->invert = 1;
+ if (optind > argc)
+ print_error("Missing pkttype class specification");
+
+ i = strtol(argv[optind - 1], &end, 16);
+ if (*end != '\0') {
+ int j = 0;
+ i = -1;
+ while (classes[j][0])
+ if (!strcasecmp(argv[optind - 1], classes[j++])) {
+ i = j - 1;
+ break;
+ }
+ }
+ if (i < 0 || i > 255)
+ print_error("Problem with specified pkttype class");
+ ptinfo->pkt_type = (uint8_t)i;
+
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+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 print(const struct ebt_u_entry *entry,
+ const struct ebt_entry_match *match)
+{
+ struct ebt_pkttype_info *pt = (struct ebt_pkttype_info *)match->data;
+ int i = 0;
+
+ printf("--pkttype-type %s", pt->invert ? "! " : "");
+ while (classes[i++][0]);
+ if (pt->pkt_type < i - 1)
+ printf("%s ", classes[pt->pkt_type]);
+ else
+ printf("%d ", pt->pkt_type);
+}
+
+static int compare(const struct ebt_entry_match *m1,
+ const struct ebt_entry_match *m2)
+{
+ struct ebt_pkttype_info *pt1 = (struct ebt_pkttype_info *)m1->data;
+ struct ebt_pkttype_info *pt2 = (struct ebt_pkttype_info *)m2->data;
+
+ if (pt1->invert != pt2->invert ||
+ pt1->pkt_type != pt2->pkt_type)
+ return 0;
+ return 1;
+}
+
+static struct ebt_u_match pkttype_match =
+{
+ EBT_PKTTYPE_MATCH,
+ sizeof(struct ebt_pkttype_info),
+ print_help,
+ init,
+ parse,
+ final_check,
+ print,
+ compare,
+ opts
+};
+
+static void _init(void) __attribute((constructor));
+static void _init(void)
+{
+ register_match(&pkttype_match);
+}
--- /dev/null Thu Aug 24 11:00:32 2000
+++ ebtables-v2.0.4/extensions/ebt_802_3.c Mon May 12 19:08:29 2003
@@ -0,0 +1,145 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include "../include/ebtables_u.h"
+#include "../include/ethernetdb.h"
+#include <linux/netfilter_bridge/ebt_802_3.h>
+
+#define _802_3_SAP '1'
+#define _802_3_TYPE '2'
+
+static struct option opts[] =
+{
+ { "802_3-sap" , required_argument, 0, _802_3_SAP },
+ { "802_3-type" , required_argument, 0, _802_3_TYPE },
+ { 0 }
+};
+
+static void print_help()
+{
+ printf(
+"802_3 options:\n"
+"--802_3-sap [!] protocol : 802.3 DSAP/SSAP- 1 byte value (hex)\n"
+" DSAP and SSAP are always the same. One SAP applies to both fields\n"
+"--802_3-type [!] protocol : 802.3 SNAP Type- 2 byte value (hex)\n"
+" Type implies SAP value 0xaa\n");
+}
+
+static void init(struct ebt_entry_match *match)
+{
+ struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data;
+
+ info->invflags = 0;
+ info->bitmask = 0;
+}
+
+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_802_3_info *info = (struct ebt_802_3_info *) (*match)->data;
+ unsigned int i;
+ char *end;
+
+ switch (c) {
+ case _802_3_SAP:
+ check_option(flags, _802_3_SAP);
+ if (check_inverse(optarg))
+ info->invflags |= EBT_802_3_SAP;
+
+ if (optind > argc)
+ print_error("Missing 802.3-sap argument");
+ i = strtoul(argv[optind - 1], &end, 16);
+ if (i > 255 || *end != '\0')
+ print_error("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:
+ check_option(flags, _802_3_TYPE);
+ if (check_inverse(optarg))
+ info->invflags |= EBT_802_3_TYPE;
+ if (optind > argc)
+ print_error("Missing 802.3-type argument");
+ i = strtoul(argv[optind - 1], &end, 16);
+ if (i > 65535 || *end != '\0') {
+ print_error("Problem with the specified "
+ "type hex value, %x",i);
+ }
+ info->type = htons(i);
+ info->bitmask |= EBT_802_3_TYPE;
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+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)
+{
+ if (!(entry->bitmask & EBT_802_3))
+ print_error("For 802.3 DSAP/SSAP filtering the protocol "
+ "must be LENGTH");
+}
+
+static void print(const struct ebt_u_entry *entry,
+ const struct ebt_entry_match *match)
+{
+ struct ebt_802_3_info *info = (struct ebt_802_3_info *)match->data;
+
+ if (info->bitmask & EBT_802_3_SAP) {
+ printf("--802_3-sap ");
+ if (info->invflags & EBT_802_3_SAP)
+ printf("! ");
+ printf("0x%.2x ", info->sap);
+ }
+ if (info->bitmask & EBT_802_3_TYPE) {
+ printf("--802_3-type ");
+ if (info->invflags & EBT_802_3_TYPE)
+ printf("! ");
+ printf("0x%.4x ", ntohs(info->type));
+ }
+}
+
+static int compare(const struct ebt_entry_match *m1,
+ const struct ebt_entry_match *m2)
+{
+ struct ebt_802_3_info *info1 = (struct ebt_802_3_info *)m1->data;
+ struct ebt_802_3_info *info2 = (struct ebt_802_3_info *)m2->data;
+
+ if (info1->bitmask != info2->bitmask)
+ return 0;
+ if (info1->invflags != info2->invflags)
+ return 0;
+ if (info1->bitmask & EBT_802_3_SAP) {
+ if (info1->sap != info2->sap)
+ return 0;
+ }
+ if (info1->bitmask & EBT_802_3_TYPE) {
+ if (info1->type != info2->type)
+ return 0;
+ }
+ return 1;
+}
+
+static struct ebt_u_match _802_3_match =
+{
+ EBT_802_3_MATCH,
+ sizeof(struct ebt_802_3_info),
+ print_help,
+ init,
+ parse,
+ final_check,
+ print,
+ compare,
+ opts
+};
+
+static void _init(void) __attribute__ ((constructor));
+static void _init(void)
+{
+ register_match(&_802_3_match);
+}
--- ebtables-v2.0.3/extensions/Makefile Fri Nov 22 20:44:37 2002
+++ ebtables-v2.0.4/extensions/Makefile Mon May 12 18:55:42 2003
@@ -1,6 +1,6 @@
#! /usr/bin/make
-EXT_FUNC+=nat arp ip standard log redirect vlan mark_m mark
+EXT_FUNC+=802_3 nat arp ip standard log redirect vlan mark_m mark pkttype
EXT_TABLES+=filter nat broute
EXT_OBJS+=$(foreach T,$(EXT_FUNC), extensions/ebt_$(T).o)
EXT_OBJS+=$(foreach T,$(EXT_TABLES), extensions/ebtable_$(T).o)
--- ebtables-v2.0.3/ChangeLog Tue Apr 1 20:07:24 2003
+++ ebtables-v2.0.4/ChangeLog Sun Jun 1 18:50:53 2003
@@ -1,3 +1,14 @@
+20030601
+ * added --Lmac2
+ * <csv_at_bluetail.com> Chris Vitale: basic 802.3/802.2 filtering
+ (experimental, kernel files are in the CVS)
+
+20030503
+ * added negative rule counter support
+ * bugfix: bcnt was not updated correctly
+ * <blancher_at_cartel-securite.fr> Cedric Blancher: add ARP MAC
+ matching support
+ * added pkttype match
20030402
* fixed check bug in ebt_ip.c (report from
joe_judge_at_guardium.com).
--- ebtables-v2.0.3/ebtables.8 Tue Apr 1 20:15:04 2003
+++ ebtables-v2.0.4/ebtables.8 Sat May 3 23:16:34 2003
@@ -26,27 +26,27 @@
.SH NAME
ebtables (v.2.0) \- Ethernet bridge frame table administration
.SH SYNOPSIS
-.BR "ebtables [-t table] -[ADI] " "chain rule-specification [match-extensions] [watcher-extensions] TARGET"
+.BR "ebtables " [ "-t table" ] " -" [ ADI ] " chain rule-specification " [ match-extensions "] [" watcher-extensions ] " TARGET"
.br
-.BR "ebtables [-t table] -P " "chain " "ACCEPT | DROP | RETURN"
+.BR "ebtables " [ "-t table" ] " -P chain ACCEPT " | " DROP " | " RETURN"
.br
-.BR "ebtables [-t table] -F [" "chain" "]"
+.BR "ebtables " [ "-t table" ] " -F " [ chain ]
.br
-.BR "ebtables [-t table] -Z [" "chain" "]"
+.BR "ebtables " [ "-t table" ] " -Z " [ chain ]
.br
-.BR "ebtables [-t table] -L [-Z] [" chain "] [ [" --Ln "] [" --Lc "] ] " | " [" --Lx "]"
+.BR "ebtables " [ "-t table" ] " -L " [ -Z "] [" " chain" "] [ [ [" --Ln "] [" --Lc "] ] | [" --Lx "] ] [" --Lmac2 "]"
.br
-.BR "ebtables [-t table] -[NX] " chain
+.BR "ebtables " [ "-t table" ] " -" [ NX ] " chain"
.br
-.BR "ebtables [-t table] -E " "old-chain-name new-chain-name"
+.BR "ebtables " [ "-t table" ] " -E old-chain-name new-chain-name"
.br
-.BR "ebtables [-t table] --init-table"
+.BR "ebtables " [ "-t table" ] " --init-table"
.br
-.BR "ebtables [-t table] [--atomic-file file] --atomic-commit
+.BR "ebtables " [ "-t table" "] [" "--atomic-file file" ] " --atomic-commit"
.br
-.BR "ebtables [-t table] [--atomic-file file] --atomic-init"
+.BR "ebtables " [ "-t table" "] [" "--atomic-file file" ] " --atomic-init"
.br
-.BR "ebtables [-t table] [--atomic-file file] --atomic-save"
+.BR "ebtables " [ "-t table" "] [" "--atomic-file file" ] " --atomic-save"
.br
.SH DESCRIPTION
.B ebtables
@@ -171,12 +171,17 @@
.B "-D, --delete"
Delete the specified rule from the selected chain. There are two ways to
use this command. The first is by specifying an interval of rule numbers
-to delete, syntax: start_nr[:end_nr]. The second usage is by specifying
-the complete rule as it would have been specified when it was added.
+to delete, syntax: start_nr[:end_nr]. Using negative numbers is allowed, for more
+details about using negative numbers, see the -I command. The second usage is by
+specifying the complete rule as it would have been specified when it was added.
.TP
.B "-I, --insert"
Insert the specified rule into the selected chain at the specified rule number.
-The number one, 1, means the head of the chain.
+If the current number of rules equals N, then the specified number can be
+between -N and N+1. For a positive number i, it holds that i and i-N-1 specify the
+same place in the chain where the rule should be inserted. The number 0 specifies
+the place past the last rule in the chain and using this number is therefore
+equivalent with using the -A command.
.TP
.B "-P, --policy"
Set the policy for the chain to the given target. The policy can be
@@ -235,8 +240,14 @@
.B "--Ln"
and
.B "--Lc"
-chain listing options,
-.B "-L."
+chain listing options.
+.br
+.B "--Lmac2"
+.br
+Shows all MAC addresses with the same length, adding leading zeroes
+if necessary. The default representation omits zeroes in the addresses
+when they are not needed.
+.br
All necessary
.B ebtables
commands for making the current list of
@@ -247,7 +258,7 @@
supplied for the
.B "-L"
command while using the
-.B "-Lx"
+.B "--Lx"
option.
.TP
.B "-N, --new-chain"
@@ -483,6 +494,12 @@
.TP
.BR "--arp-ip-dst " "[!] \fIaddress\fP[/\fImask\fP]"
The ARP IP destination address specification.
+.TP
+.BR "--arp-mac-src " "[!] \fIaddress\fP[/\fImask\fP]"
+The ARP MAC source address specification.
+.TP
+.BR "--arp-mac-dst " "[!] \fIaddress\fP[/\fImask\fP]"
+The ARP MAC destination address specification.
.SS ip
Specify ip fields. These will only work if the protocol equals
.BR IPv4 .
@@ -530,6 +547,14 @@
mark value. If only a mask is specified (start with '/') the logical AND
of the mark value of the frame and the user-specified mark is taken and
the result is compared with zero.
+.SS pkttype
+.TP
+.BR "--pkttype-type " "[!] \fItype\fP"
+Matches on the Ethernet "class" of the frame, which is determined by the
+generic networking code. Possible values: broadcast (MAC destination is
+broadcast address), multicast (MAC destination is multicast address),
+host (MAC destination is the receiving network device) or otherhost
+(none of the above).
.SS vlan
Specify 802.1Q Tag Control Information fields.
The protocol rule specification (frame type) should be set to
--- ebtables-v2.0.3/include/ebtables_u.h Sun Jan 19 12:37:52 2003
+++ ebtables-v2.0.4/include/ebtables_u.h Sun May 4 18:51:43 2003
@@ -208,10 +208,14 @@
void deliver_table(struct ebt_u_replace *repl);
void check_option(unsigned int *flags, unsigned int mask);
int check_inverse(const char option[]);
+void print_mac(const char *mac);
+void print_mac_and_mask(const char *mac, const char *mask);
+int ebtables_insmod(const char *modname);
void __print_bug(char *file, int line, char *format, ...);
#define print_bug(format, args...) \
__print_bug(__FILE__, __LINE__, format, ##args)
-#define print_error(format,args...) {printf(format".\n",##args); exit(-1);}
+#define print_error(format,args...) {printf(format,##args);\
+ printf(".\n");exit(-1);}
#define print_memory() {printf("Ebtables: " __FILE__ \
" %s %d :Out of memory.\n", __FUNCTION__, __LINE__); exit(-1);}